ipaacar_core/components/iu/
links.rs
1use crate::components::iu::core::IUCoreError;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5#[derive(Default, Debug, Serialize, Deserialize, Clone)]
7pub struct IULinks {
8 pub link_map: HashMap<String, Vec<String>>,
9}
10
11impl IULinks {
12 pub fn add_target_to_link(&mut self, link_name: &str, target: impl Into<String>) {
13 if let Some(v) = self.link_map.get_mut(link_name) {
14 v.push(target.into());
15 } else {
16 self.link_map
17 .insert(link_name.to_string(), vec![target.into()]);
18 }
19 }
20
21 pub fn remove_target_from_link(
22 &mut self,
23 link_name: &str,
24 target: &str,
25 ) -> Result<(), IUCoreError> {
26 if let Some(v) = self.link_map.get_mut(link_name) {
27 if let Some(i) = v.iter().position(|x| x == target) {
28 v.remove(i);
29 if v.is_empty() {
30 self.remove_link(link_name)?;
31 }
32 Ok(())
33 } else {
34 Err(IUCoreError::LinkTargetNotFound)
35 }
36 } else {
37 Err(IUCoreError::LinkNotFound)
38 }
39 }
40
41 pub fn remove_link(&mut self, link_name: &str) -> Result<(), IUCoreError> {
42 self.link_map
43 .remove(link_name)
44 .ok_or(IUCoreError::LinkNotFound)
45 .map(|_| ())
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use crate::components::iu::core::IUCoreError;
52 use crate::components::iu::links::IULinks;
53 use std::collections::HashMap;
54
55 #[test]
56 fn iu_link_test() {
57 let mut iu_links = IULinks::default();
58 iu_links.add_target_to_link("grounded-in", "abc");
59 iu_links.add_target_to_link("grounded-in", "def");
60 iu_links.add_target_to_link("grounded-in", "fff");
61 iu_links.add_target_to_link("joy", "fff");
62 iu_links.add_target_to_link("joy", "ddd");
63
64 assert_eq!(
65 iu_links.link_map,
66 HashMap::from([
67 (
68 "grounded-in".to_string(),
69 vec!["abc".to_string(), "def".to_string(), "fff".to_string()]
70 ),
71 (
72 "joy".to_string(),
73 vec!["fff".to_string(), "ddd".to_string()]
74 )
75 ])
76 );
77
78 iu_links
79 .remove_target_from_link("grounded-in", "def")
80 .unwrap();
81 assert_eq!(
82 iu_links.remove_target_from_link("grounded-in", "def"),
83 Err(IUCoreError::LinkTargetNotFound)
84 );
85 assert_eq!(
86 iu_links.remove_target_from_link("grounded-in", "ggg"),
87 Err(IUCoreError::LinkTargetNotFound)
88 );
89 assert_eq!(
90 iu_links.remove_target_from_link("ggg", "gdddd-in"),
91 Err(IUCoreError::LinkNotFound)
92 );
93
94 iu_links
95 .remove_target_from_link("grounded-in", "abc")
96 .unwrap();
97 iu_links
98 .remove_target_from_link("grounded-in", "fff")
99 .unwrap();
100
101 assert_eq!(
102 iu_links.remove_link("grounded-in"),
103 Err(IUCoreError::LinkNotFound)
104 );
105
106 iu_links.remove_link("joy").unwrap();
107
108 assert_eq!(iu_links.link_map, HashMap::default())
109 }
110}