1+ use std:: { collections:: { HashMap , HashSet } , hash:: Hash , fmt:: Display } ;
2+
3+ struct Node < T > {
4+ value : T ,
5+ relatives : HashSet < T > ,
6+ }
7+
8+ impl < T : Eq + Hash > Node < T > {
9+ pub fn new ( value : T ) -> Self {
10+ Self {
11+ value,
12+ relatives : HashSet :: new ( ) ,
13+ }
14+ }
15+
16+ pub fn add_relative ( & mut self , value : T ) {
17+ self . relatives . insert ( value) ;
18+ }
19+
20+ pub fn remove_relative ( & mut self , value : & T ) {
21+ if !self . has_relative ( value) {
22+ return ;
23+ }
24+
25+ self . relatives . retain ( |relative| * relative != * value) ;
26+ }
27+
28+ pub fn has_relative ( & self , value : & T ) -> bool {
29+ self . relatives . contains ( value)
30+ }
31+ }
32+
33+ impl < T : Eq + Hash + Display > Display for Node < T > {
34+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
35+ if self . relatives . len ( ) == 0 {
36+ return Ok ( ( ) ) ;
37+ }
38+
39+ let mut formatted_relatives = String :: new ( ) ;
40+
41+ for ( index, relative) in self . relatives . iter ( ) . enumerate ( ) {
42+ let delimeter = if index == self . relatives . len ( ) - 1 { "" } else { ", " } ;
43+
44+ formatted_relatives. push_str ( & ( relative. to_string ( ) + delimeter) ) ;
45+ }
46+
47+ let formatted_node = format ! ( "{} is connected with [{}]" , self . value. to_string( ) , formatted_relatives) ;
48+
49+ writeln ! ( f, "{}" , formatted_node) ?;
50+
51+ Ok ( ( ) )
52+ }
53+ }
54+
55+ pub struct Graph < T > {
56+ nodes : HashMap < T , Box < Node < T > > > ,
57+ }
58+
59+ impl < T : Eq + Hash + Clone > Graph < T > {
60+ pub fn new ( ) -> Self {
61+ Self {
62+ nodes : HashMap :: new ( ) ,
63+ }
64+ }
65+
66+ pub fn add_node ( & mut self , value : T ) {
67+ self . nodes . entry ( value. clone ( ) ) . or_insert ( Box :: new ( Node :: new ( value) ) ) ;
68+ }
69+
70+ pub fn remove_node ( & mut self , value : T ) -> Result < ( ) , & ' static str > {
71+ if !self . is_node_exists ( & value) {
72+ return Err ( "Node is not exist" ) ;
73+ }
74+
75+ for node in self . nodes . values_mut ( ) {
76+ node. remove_relative ( & value) ;
77+ }
78+
79+ self . nodes . remove ( & value) ;
80+
81+ Ok ( ( ) )
82+ }
83+
84+ pub fn add_edge ( & mut self , from : & T , to : T ) -> Result < ( ) , & ' static str > {
85+ if !self . is_node_exists ( from) {
86+ return Err ( "From node is not exist" ) ;
87+ }
88+
89+ if !self . is_node_exists ( & to) {
90+ return Err ( "To node is not exist" ) ;
91+ }
92+
93+ let node = self . nodes . get_mut ( from) . unwrap ( ) ;
94+
95+ node. add_relative ( to) ;
96+
97+ Ok ( ( ) )
98+ }
99+
100+ pub fn remove_edge ( & mut self , from : & T , to : & T ) {
101+ if !self . is_node_exists ( from) || !self . is_node_exists ( to) {
102+ return ;
103+ }
104+
105+ let node = self . nodes . get_mut ( from) . unwrap ( ) ;
106+
107+ node. remove_relative ( to) ;
108+ }
109+
110+ fn is_node_exists ( & self , value : & T ) -> bool {
111+ self . nodes . get ( value) . is_some ( )
112+ }
113+ }
114+
115+ impl < T : Eq + Hash + Display > Display for Graph < T > {
116+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
117+ let mut formatted_graph = String :: new ( ) ;
118+
119+ for node in self . nodes . values ( ) {
120+ formatted_graph. push_str ( & node. to_string ( ) ) ;
121+ }
122+
123+ write ! ( f, "{}" , formatted_graph) ?;
124+
125+ Ok ( ( ) )
126+ }
127+ }
0 commit comments