1use derive_more::Deref;
2use getset::{Getters, WithSetters};
3use indexmap::IndexMap;
4use serde_derive::{Deserialize, Serialize};
5
6use crate::vars::types::UpperKey;
7
8use super::{
9 EnvDict, EnvEvaluable, ValueDict, VarCollection, definition::Mutability, dict::ValueMap,
10 types::ValueType,
11};
12
13pub type OriginMap = IndexMap<UpperKey, OriginValue>;
14
15impl EnvEvaluable<OriginMap> for OriginMap {
16 fn env_eval(self, dict: &EnvDict) -> OriginMap {
17 let mut cur_dict = dict.clone();
18 let mut vmap = OriginMap::new();
19 for (k, v) in self {
20 let e_v = v.env_eval(&cur_dict);
21 if !cur_dict.contains_key(&k) {
22 cur_dict.insert(k.clone(), e_v.value.clone());
23 }
24 vmap.insert(k, e_v);
25 }
26 vmap
27 }
28}
29
30#[derive(Getters, Clone, Debug, Serialize, Deserialize, PartialEq, WithSetters)]
31#[getset(get = "pub")]
32pub struct OriginValue {
33 origin: Option<String>,
34 value: ValueType,
35 #[getset(get = "pub", set_with = "pub")]
37 #[serde(default, skip_serializing_if = "Mutability::is_default")]
38 mutability: Mutability,
39}
40
41impl EnvEvaluable<OriginValue> for OriginValue {
42 fn env_eval(self, dict: &EnvDict) -> OriginValue {
43 Self {
44 origin: self.origin,
45 value: self.value.env_eval(dict),
46 mutability: self.mutability,
47 }
48 }
49}
50
51#[derive(Getters, Clone, Debug, Serialize, Deserialize, PartialEq, Deref, Default)]
52pub struct OriginDict {
53 dict: OriginMap,
54}
55impl EnvEvaluable<OriginDict> for OriginDict {
56 fn env_eval(self, dict: &EnvDict) -> OriginDict {
57 Self {
58 dict: self.dict.env_eval(dict),
59 }
60 }
61}
62
63impl From<ValueType> for OriginValue {
64 fn from(value: ValueType) -> Self {
65 Self {
66 value,
67 origin: None,
68 mutability: Mutability::default(),
69 }
70 }
71}
72impl From<&str> for OriginValue {
73 fn from(value: &str) -> Self {
74 Self {
75 origin: None,
76 value: ValueType::from(value),
77 mutability: Mutability::default(),
78 }
79 }
80}
81
82impl OriginValue {
83 pub fn with_origin<S: Into<String>>(mut self, origin: S) -> Self {
84 self.origin = Some(origin.into());
85 self
86 }
87 pub fn is_mutable(&self) -> bool {
88 match self.mutability {
89 Mutability::Immutable => false,
90 Mutability::System | Mutability::Module => true,
91 }
92 }
93}
94
95impl From<ValueDict> for OriginDict {
96 fn from(value: ValueDict) -> Self {
97 let mut dict = OriginMap::new();
98 for (k, v) in value.dict() {
99 dict.insert(k.clone(), OriginValue::from(v.clone()));
100 }
101 Self { dict }
102 }
103}
104impl From<VarCollection> for OriginDict {
105 fn from(value: VarCollection) -> Self {
106 let mut dict = OriginMap::new();
107 for item in value.immutable_vars() {
108 dict.insert(
109 item.name().to_string().into(),
110 OriginValue::from(item.value().clone()).with_mutability(item.mutability().clone()),
111 );
112 }
113 for item in value.system_vars() {
114 dict.insert(
115 item.name().to_string().into(),
116 OriginValue::from(item.value().clone()).with_mutability(item.mutability().clone()),
117 );
118 }
119 for item in value.module_vars() {
120 dict.insert(
121 item.name().to_string().into(),
122 OriginValue::from(item.value().clone()).with_mutability(item.mutability().clone()),
123 );
124 }
125
126 Self { dict }
127 }
128}
129
130impl OriginDict {
131 pub fn new() -> Self {
132 Self {
133 dict: OriginMap::new(),
134 }
135 }
136
137 pub fn insert<S: Into<UpperKey>>(&mut self, k: S, v: ValueType) -> Option<OriginValue> {
138 self.dict.insert(k.into(), OriginValue::from(v))
139 }
140 pub fn set_source<S: Into<String> + Clone>(&mut self, label: S) {
141 for x in self.dict.values_mut() {
142 if x.origin().is_none() {
143 x.origin = Some(label.clone().into());
144 }
145 }
146 }
147 pub fn with_origin<S: Into<String> + Clone>(mut self, label: S) -> Self {
148 for x in self.dict.values_mut() {
149 if x.origin().is_none() {
150 x.origin = Some(label.clone().into());
151 }
152 }
153 self
154 }
155 pub fn merge(&mut self, other: &Self) {
156 for (k, v) in other.iter() {
157 if let Some(x) = self.get(k) {
158 if x.is_mutable() {
160 self.dict.insert(k.clone(), v.clone());
161 }
162 } else {
163 self.dict.insert(k.clone(), v.clone());
164 }
165 }
166 }
167 pub fn export_value(&self) -> ValueMap {
168 let mut map = ValueMap::new();
169 for (k, v) in &self.dict {
170 map.insert(k.clone(), v.value().clone());
171 }
172 map
173 }
174 pub fn export_dict(&self) -> ValueDict {
175 ValueDict::from(self.export_value())
176 }
177 pub fn export_origin(&self) -> OriginMap {
178 let mut map = OriginMap::new();
179 for (k, v) in &self.dict {
180 map.insert(k.clone(), v.clone());
181 }
182 map
183 }
184 pub fn get_case_insensitive<S: AsRef<str>>(&self, key: S) -> Option<&OriginValue> {
185 let upper_key = UpperKey::from(key.as_ref());
186 self.dict.get(&upper_key)
187 }
188 #[deprecated(note = "renamed to get_case_insensitive()")]
189 pub fn ucase_get<S: AsRef<str>>(&self, key: S) -> Option<&OriginValue> {
190 self.get_case_insensitive(key)
191 }
192}
193
194#[cfg(test)]
195mod tests {
196 use super::*;
197 use crate::vars::dict::ValueDict;
198
199 #[test]
200 fn test_origin_value_from_value_type() {
201 let value = ValueType::from("test_value");
202 let origin_value = OriginValue::from(value);
203 assert_eq!(origin_value.origin().as_ref(), None);
204 assert_eq!(origin_value.value(), &ValueType::from("test_value"));
205 }
206
207 #[test]
208 fn test_origin_value_from_str() {
209 let origin_value = OriginValue::from("test_string");
210 assert_eq!(origin_value.origin().as_ref(), None);
211 assert_eq!(origin_value.value(), &ValueType::from("test_string"));
212 }
213
214 #[test]
215 fn test_origin_value_with_origin() {
216 let origin_value = OriginValue::from("test_value").with_origin("test_origin");
217 assert_eq!(
218 origin_value.origin().as_ref(),
219 Some(&"test_origin".to_string())
220 );
221 assert_eq!(origin_value.value(), &ValueType::from("test_value"));
222 }
223
224 #[test]
225 fn test_origin_value_env_eval() {
226 let mut env_dict = EnvDict::new();
227 env_dict.insert("TEST_VAR", "replaced_value".into());
228
229 let origin_value = OriginValue::from("prefix_${TEST_VAR}_suffix");
230 let evaluated = origin_value.env_eval(&env_dict);
231
232 assert_eq!(evaluated.origin().as_ref(), None);
233 assert_eq!(
234 evaluated.value(),
235 &ValueType::from("prefix_replaced_value_suffix")
236 );
237 }
238
239 #[test]
240 fn test_origin_value_env_eval_with_origin() {
241 let mut env_dict = EnvDict::new();
242 env_dict.insert("TEST_VAR", "replaced_value".into());
243
244 let origin_value =
245 OriginValue::from("prefix_${TEST_VAR}_suffix").with_origin("test_origin");
246 let evaluated = origin_value.env_eval(&env_dict);
247
248 assert_eq!(
249 evaluated.origin().as_ref(),
250 Some(&"test_origin".to_string())
251 );
252 assert_eq!(
253 evaluated.value(),
254 &ValueType::from("prefix_replaced_value_suffix")
255 );
256 }
257
258 #[test]
259 fn test_origin_dict_new() {
260 let dict = OriginDict::new();
261 assert!(dict.is_empty());
262 assert_eq!(dict.len(), 0);
263 }
264
265 #[test]
266 fn test_origin_dict_insert() {
267 let mut dict = OriginDict::new();
268 let result = dict.insert("key1", ValueType::from("value1"));
269 assert_eq!(result, None);
270
271 let result = dict.insert("key1", ValueType::from("new_value"));
272 assert!(result.is_some());
273
274 assert_eq!(dict.len(), 1);
275 assert_eq!(
276 dict.get("KEY1").unwrap().value(),
277 &ValueType::from("new_value")
278 );
279 }
280
281 #[test]
282 fn test_origin_dict_set_source() {
283 let mut dict = OriginDict::new();
284 dict.insert("key1", ValueType::from("value1"));
285 dict.insert("key2", ValueType::from("value2"));
286
287 dict.set_source("new_source");
288
289 assert_eq!(
290 dict.get("KEY1").unwrap().origin().as_ref(),
291 Some(&"new_source".to_string())
292 );
293 assert_eq!(
294 dict.get("KEY2").unwrap().origin().as_ref(),
295 Some(&"new_source".to_string())
296 );
297 }
298
299 #[test]
300 fn test_origin_dict_merge() {
301 let mut dict1 = OriginDict::new();
302 dict1.insert("key1", ValueType::from("value1"));
303 dict1.insert("key2", ValueType::from("value2"));
304
305 let mut dict2 = OriginDict::new();
306 dict2.insert("key2", ValueType::from("new_value2"));
307 dict2.insert("key3", ValueType::from("value3"));
308
309 dict1.merge(&dict2);
310
311 assert_eq!(dict1.len(), 3);
312 assert_eq!(
313 dict1.get("KEY1").unwrap().value(),
314 &ValueType::from("value1")
315 );
316 assert_eq!(
317 dict1.get("KEY2").unwrap().value(),
318 &ValueType::from("new_value2")
319 );
320 assert_eq!(
321 dict1.get("KEY3").unwrap().value(),
322 &ValueType::from("value3")
323 );
324 }
325
326 #[test]
327 fn test_origin_dict_export_value() {
328 let mut dict = OriginDict::new();
329 dict.insert("key1", ValueType::from("value1"));
330 dict.insert("key2", ValueType::from("value2"));
331
332 let value_map = dict.export_value();
333
334 assert_eq!(value_map.len(), 2);
335 assert_eq!(value_map.get("KEY1"), Some(&ValueType::from("value1")));
336 assert_eq!(value_map.get("KEY2"), Some(&ValueType::from("value2")));
337 }
338
339 #[test]
340 fn test_origin_dict_export_dict() {
341 let mut dict = OriginDict::new();
342 dict.insert("key1", ValueType::from("value1"));
343 dict.insert("key2", ValueType::from("value2"));
344
345 let value_dict = dict.export_dict();
346
347 assert_eq!(value_dict.len(), 2);
348 assert_eq!(value_dict.get("KEY1"), Some(&ValueType::from("value1")));
349 assert_eq!(value_dict.get("KEY2"), Some(&ValueType::from("value2")));
350 }
351
352 #[test]
353 fn test_origin_dict_export_origin() {
354 let mut dict = OriginDict::new();
355 dict.insert("key1", ValueType::from("value1"));
356 dict.insert("key2", ValueType::from("value2"));
357
358 dict.set_source("origin1");
360
361 let origin_map = dict.export_origin();
362
363 assert_eq!(origin_map.len(), 2);
364 assert_eq!(
365 origin_map.get("KEY1").unwrap().origin().as_ref(),
366 Some(&"origin1".to_string())
367 );
368 assert_eq!(
369 origin_map.get("KEY2").unwrap().origin().as_ref(),
370 Some(&"origin1".to_string())
371 );
372 }
373
374 #[test]
375 fn test_origin_dict_from_value_dict() {
376 let mut value_dict = ValueDict::new();
377 value_dict.insert("key1", ValueType::from("value1"));
378 value_dict.insert("key2", ValueType::from("value2"));
379
380 let origin_dict = OriginDict::from(value_dict);
381
382 assert_eq!(origin_dict.len(), 2);
383 assert_eq!(
384 origin_dict.get("KEY1").unwrap().value(),
385 &ValueType::from("value1")
386 );
387 assert_eq!(
388 origin_dict.get("KEY2").unwrap().value(),
389 &ValueType::from("value2")
390 );
391 assert_eq!(origin_dict.get("KEY1").unwrap().origin().as_ref(), None);
392 assert_eq!(origin_dict.get("KEY2").unwrap().origin().as_ref(), None);
393 }
394
395 #[test]
396 fn test_origin_map_env_eval() {
397 let mut origin_map = OriginMap::new();
398 origin_map.insert(
399 "key1".to_string().into(),
400 OriginValue::from("prefix_${TEST_VAR}_suffix"),
401 );
402 origin_map.insert(
403 "key2".to_string().into(),
404 OriginValue::from("static_value").with_origin("test_origin"),
405 );
406
407 let mut env_dict = EnvDict::new();
408 env_dict.insert("TEST_VAR", "replaced_value".into());
409
410 let evaluated_map = origin_map.env_eval(&env_dict);
411
412 assert_eq!(evaluated_map.len(), 2);
413 assert_eq!(
414 evaluated_map.get("KEY1").unwrap().value(),
415 &ValueType::from("prefix_replaced_value_suffix")
416 );
417 assert_eq!(evaluated_map.get("KEY1").unwrap().origin().as_ref(), None);
418 assert_eq!(
419 evaluated_map.get("KEY2").unwrap().value(),
420 &ValueType::from("static_value")
421 );
422 assert_eq!(
423 evaluated_map.get("KEY2").unwrap().origin().as_ref(),
424 Some(&"test_origin".to_string())
425 );
426 }
427
428 #[test]
429 fn test_origin_value_clone() {
430 let origin_value = OriginValue::from("test_value").with_origin("test_origin");
431 let cloned = origin_value.clone();
432
433 assert_eq!(cloned, origin_value);
434 assert_eq!(cloned.origin().as_ref(), Some(&"test_origin".to_string()));
435 assert_eq!(cloned.value(), &ValueType::from("test_value"));
436 }
437
438 #[test]
439 fn test_origin_dict_clone() {
440 let mut dict = OriginDict::new();
441 dict.insert("key1", ValueType::from("value1"));
442 dict.insert("key2", ValueType::from("value2"));
443
444 dict.set_source("origin1");
446
447 let cloned = dict.clone();
448
449 assert_eq!(cloned, dict);
450 assert_eq!(cloned.len(), 2);
451 assert_eq!(
452 cloned.get("KEY1").unwrap().origin().as_ref(),
453 Some(&"origin1".to_string())
454 );
455 assert_eq!(
456 cloned.get("KEY2").unwrap().origin().as_ref(),
457 Some(&"origin1".to_string())
458 );
459 }
460
461 #[test]
462 fn test_origin_value_debug() {
463 let origin_value = OriginValue::from("test_value").with_origin("test_origin");
464 let debug_str = format!("{origin_value:?}");
465
466 assert!(debug_str.contains("OriginValue"));
467 assert!(debug_str.contains("test_origin"));
468 assert!(debug_str.contains("test_value"));
469 }
470
471 #[test]
472 fn test_origin_dict_debug() {
473 let mut dict = OriginDict::new();
474 dict.insert("key1", ValueType::from("value1"));
475
476 let debug_str = format!("{dict:?}");
477
478 assert!(debug_str.contains("OriginDict"));
479 assert!(debug_str.contains("KEY1"));
480 assert!(debug_str.contains("value1"));
481 }
482
483 #[test]
484 fn test_origin_dict_default() {
485 let dict: OriginDict = OriginDict::default();
486 assert!(dict.is_empty());
487 assert_eq!(dict.len(), 0);
488 }
489
490 #[test]
491 fn test_origin_dict_deref() {
492 let mut dict = OriginDict::new();
493 dict.insert("key1", ValueType::from("value1"));
494 dict.insert("key2", ValueType::from("value2"));
495
496 let map: &OriginMap = &dict;
498 assert_eq!(map.len(), 2);
499 assert!(map.contains_key("KEY1"));
500 assert!(map.contains_key("KEY2"));
501 }
502
503 #[test]
504 fn test_origin_dict_partial_eq() {
505 let mut dict1 = OriginDict::new();
506 dict1.insert("key1", ValueType::from("value1"));
507 dict1.insert("key2", ValueType::from("value2"));
508
509 let mut dict2 = OriginDict::new();
510 dict2.insert("key1", ValueType::from("value1"));
511 dict2.insert("key2", ValueType::from("value2"));
512
513 let mut dict3 = OriginDict::new();
514 dict3.insert("key1", ValueType::from("value1"));
515 dict3.insert("key2", ValueType::from("different_value"));
516
517 assert_eq!(dict1, dict2);
518 assert_ne!(dict1, dict3);
519 }
520
521 #[test]
522 fn test_origin_value_partial_eq() {
523 let value1 = OriginValue::from("test_value").with_origin("test_origin");
524 let value2 = OriginValue::from("test_value").with_origin("test_origin");
525 let value3 = OriginValue::from("different_value").with_origin("test_origin");
526 let value4 = OriginValue::from("test_value").with_origin("different_origin");
527
528 assert_eq!(value1, value2);
529 assert_ne!(value1, value3);
530 assert_ne!(value1, value4);
531 }
532}
533
534#[cfg(test)]
535mod change_scope_tests {
536 use super::*;
537 use crate::vars::definition::Mutability;
538
539 #[test]
540 fn test_origin_value_is_mutable() {
541 let immutable_value = OriginValue {
542 origin: None,
543 value: ValueType::from("test"),
544 mutability: Mutability::Immutable,
545 };
546 assert!(!immutable_value.is_mutable());
547
548 let public_value = OriginValue {
549 origin: None,
550 value: ValueType::from("test"),
551 mutability: Mutability::System,
552 };
553 assert!(public_value.is_mutable());
554
555 let model_value = OriginValue {
556 origin: None,
557 value: ValueType::from("test"),
558 mutability: Mutability::Module,
559 };
560 assert!(model_value.is_mutable());
561 }
562
563 #[test]
564 fn test_origin_value_from_value_type() {
565 let value = OriginValue::from(ValueType::from("test"));
566 assert_eq!(value.mutability(), &Mutability::Module);
567 assert!(value.is_mutable());
568 }
569
570 #[test]
571 fn test_origin_value_from_str() {
572 let value = OriginValue::from("test");
573 assert_eq!(value.mutability(), &Mutability::Module);
574 assert!(value.is_mutable());
575 }
576
577 #[test]
578 fn test_origin_value_scope_getter_setter() {
579 let mut value = OriginValue::from("test");
580 assert_eq!(value.mutability(), &Mutability::Module);
581
582 value = value.with_mutability(Mutability::Immutable);
583 assert_eq!(value.mutability(), &Mutability::Immutable);
584 assert!(!value.is_mutable());
585
586 value = value.with_mutability(Mutability::Module);
587 assert_eq!(value.mutability(), &Mutability::Module);
588 assert!(value.is_mutable());
589 }
590
591 #[test]
592 fn test_origin_value_with_origin() {
593 let value = OriginValue::from("test").with_origin("test_source");
594 assert_eq!(value.origin(), &Some("test_source".to_string()));
595 assert_eq!(value.mutability(), &Mutability::Module);
596 }
597
598 #[test]
599 fn test_origin_value_env_eval() {
600 let mut env_dict = EnvDict::new();
601 env_dict.insert("TEST_VAR".to_string(), ValueType::from("replaced"));
602
603 let value = OriginValue {
604 origin: Some("test_origin".to_string()),
605 value: ValueType::from("prefix_${TEST_VAR}_suffix"),
606 mutability: Mutability::Immutable,
607 };
608
609 let evaluated = value.env_eval(&env_dict);
610 assert_eq!(evaluated.origin(), &Some("test_origin".to_string()));
611 assert_eq!(
612 evaluated.value(),
613 &ValueType::from("prefix_replaced_suffix")
614 );
615 assert_eq!(evaluated.mutability(), &Mutability::Immutable);
616 assert!(!evaluated.is_mutable());
617 }
618
619 #[test]
620 fn test_origin_value_serialization() {
621 let value = OriginValue {
622 origin: Some("test_origin".to_string()),
623 value: ValueType::from("test_value"),
624 mutability: Mutability::System,
625 };
626
627 let json = serde_json::to_string(&value).unwrap();
629 assert!(!json.contains("scope"));
630
631 let immutable_value = OriginValue {
633 origin: Some("test_origin".to_string()),
634 value: ValueType::from("test_value"),
635 mutability: Mutability::Immutable,
636 };
637
638 let json_immutable = serde_json::to_string(&immutable_value).unwrap();
639 assert!(json_immutable.contains("mutability"));
640 }
641}