Skip to main content

orion_variate/vars/
origin.rs

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    /// 替换原有的 immutable: Option<bool>
36    #[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                //replace orion value;
159                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        // 先设置source
359        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        // 设置source来测试origin
445        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        // Test deref to OriginMap
497        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        // 默认的 Public scope 应该被跳过序列化
628        let json = serde_json::to_string(&value).unwrap();
629        assert!(!json.contains("scope"));
630
631        // Non-Default scope 应该被序列化
632        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}