biodivine_lib_param_bn/_impl_annotations/
_impl_annotation.rs1use crate::_impl_annotations::validate_path_segment;
2use crate::ModelAnnotation;
3use std::collections::HashMap;
4use std::fmt::{Debug, Formatter};
5
6impl ModelAnnotation {
7 pub fn new() -> ModelAnnotation {
9 ModelAnnotation {
10 value: Default::default(),
11 inner: Default::default(),
12 }
13 }
14
15 pub fn with_value(value: String) -> ModelAnnotation {
17 ModelAnnotation {
18 value: Some(value),
19 inner: Default::default(),
20 }
21 }
22
23 pub fn get_child<T: AsRef<str>>(&self, path: &[T]) -> Option<&ModelAnnotation> {
27 if path.is_empty() {
28 Some(self)
29 } else {
30 self.inner
31 .get(path[0].as_ref())
32 .and_then(|inner| inner.get_child(&path[1..]))
33 }
34 }
35
36 pub fn get_mut_child<T: AsRef<str>>(&mut self, path: &[T]) -> Option<&mut ModelAnnotation> {
41 if path.is_empty() {
42 Some(self)
43 } else {
44 self.inner
45 .get_mut(path[0].as_ref())
46 .and_then(|inner| inner.get_mut_child(&path[1..]))
47 }
48 }
49
50 pub fn ensure_child<T: AsRef<str>>(&mut self, path: &[T]) -> &mut ModelAnnotation {
55 if path.is_empty() {
56 self
57 } else {
58 validate_path_segment(path[0].as_ref());
60 let entry = self.inner.entry(path[0].as_ref().to_string()).or_default();
61 entry.ensure_child(&path[1..])
62 }
63 }
64
65 pub fn ensure_value<T: AsRef<str>>(&mut self, path: &[T], value: &str) -> bool {
69 let annotation = self.ensure_child(path);
70 if let Some(current) = annotation.value.as_ref() {
71 if current == value {
72 false
73 } else {
74 annotation.value = Some(value.to_string());
75 true
76 }
77 } else {
78 annotation.value = Some(value.to_string());
79 true
80 }
81 }
82
83 pub fn append_value<T: AsRef<str>>(&mut self, path: &[T], value: &str) {
89 let annotation = self.ensure_child(path);
90 if let Some(current) = annotation.value.as_mut() {
91 current.push_str(value);
92 } else {
93 annotation.value = Some(value.to_string());
94 }
95 }
96
97 pub fn get_value<T: AsRef<str>>(&self, path: &[T]) -> Option<&String> {
100 if path.is_empty() {
101 self.value.as_ref()
102 } else {
103 self.inner
104 .get(path[0].as_ref())
105 .and_then(|inner| inner.get_value(&path[1..]))
106 }
107 }
108
109 pub fn value(&self) -> Option<&String> {
111 self.value.as_ref()
112 }
113
114 pub fn value_mut(&mut self) -> &mut Option<String> {
116 &mut self.value
117 }
118
119 pub fn children(&self) -> &HashMap<String, ModelAnnotation> {
121 &self.inner
122 }
123
124 pub fn children_mut(&mut self) -> &mut HashMap<String, ModelAnnotation> {
126 &mut self.inner
127 }
128}
129
130impl Default for ModelAnnotation {
131 fn default() -> Self {
132 ModelAnnotation::new()
133 }
134}
135
136impl Debug for ModelAnnotation {
137 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
138 write!(f, "Annotation[{:?}][", self.value)?;
139 let mut keys = self.inner.keys().collect::<Vec<_>>();
141 keys.sort();
142 for k in keys {
143 write!(f, "(`{}` : {:?})", k, self.inner.get(k).unwrap())?;
144 }
145 write!(f, "]")
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use crate::ModelAnnotation;
152
153 #[test]
154 pub fn simple_annotation_test() {
155 let mut annotation = ModelAnnotation::default();
156
157 assert!(annotation.children().is_empty());
158 assert!(annotation.value().is_none());
159
160 assert!(annotation.ensure_value::<&str>(&[], "Value 1"));
162 assert_eq!("Value 1", annotation.value().unwrap().as_str());
163 assert!(!annotation.ensure_value::<&str>(&[], "Value 1"));
164
165 annotation.ensure_value::<&str>(&[], "Hello\n");
167 annotation.append_value::<&str>(&[], "World\n");
168 assert_eq!("Hello\nWorld\n", annotation.value().unwrap().as_str());
169
170 annotation.value_mut().as_mut().unwrap().push_str("Value 3");
172 assert_eq!(
173 "Hello\nWorld\nValue 3",
174 annotation.value().unwrap().as_str()
175 );
176
177 annotation.children_mut().insert(
178 "Child 1".to_string(),
179 ModelAnnotation::with_value("Child value".to_string()),
180 );
181 assert!(annotation.get_child(&["Child 1"]).is_some());
182 assert_eq!(
183 "Child value",
184 annotation.get_value(&["Child 1"]).unwrap().as_str()
185 );
186
187 assert!(annotation.get_child(&["Child 1", "Child 2"]).is_none());
188 annotation.ensure_child(&["Child 1", "Child 2"]);
189 assert!(annotation.get_child(&["Child 1", "Child 2"]).is_some());
190 }
191
192 #[test]
193 #[should_panic]
194 pub fn add_invalid_annotation_child() {
195 let mut annotation = ModelAnnotation::default();
197 annotation.ensure_child(&["va`R`"]);
198 }
199
200 #[test]
201 #[should_panic]
202 pub fn print_invalid_annotation() {
203 let mut annotations = ModelAnnotation::default();
204 annotations.children_mut().insert(
205 "hello\nworld".to_string(),
206 ModelAnnotation::with_value("Value".to_string()),
207 );
208 annotations.to_string();
209 }
210}