Skip to main content

orion_variate/vars/
definition.rs

1use getset::{Getters, Setters, WithSetters};
2use serde_derive::{Deserialize, Serialize};
3
4use super::ValueType;
5
6#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
7pub enum Mutability {
8    /// 不可变变量,不允许任何修改
9    Immutable,
10    /// 公开可变变量,允许在任何上下文中修改
11    System,
12    /// 模块级可变变量,只在同一模块内允许修改
13    #[default]
14    Module,
15}
16
17impl Mutability {
18    /// 检查是否为默认值,用于序列化优化
19    pub fn is_default(&self) -> bool {
20        matches!(self, Mutability::Module)
21    }
22
23    /// 创建不可变作用域
24    pub fn immutable() -> Self {
25        Mutability::Immutable
26    }
27
28    /// 创建公开可变作用域
29    pub fn system() -> Self {
30        Mutability::System
31    }
32
33    /// 创建模块级可变作用域
34    pub fn module() -> Self {
35        Mutability::Module
36    }
37
38    #[deprecated(note = "renamed to module() for clarity")]
39    pub fn model() -> Self {
40        Self::Module
41    }
42
43    /// 为向后兼容,从旧格式的 Option<bool> 转换
44    pub fn from_immutable_flag(immutable: Option<bool>) -> Self {
45        match immutable {
46            Some(true) => Mutability::Immutable,
47            Some(false) | None => Mutability::System,
48        }
49    }
50
51    /// 转换为旧格式,用于向后兼容
52    pub fn to_immutable_flag(&self) -> Option<bool> {
53        match self {
54            Mutability::Immutable => Some(true),
55            Mutability::System | Mutability::Module => Some(false),
56        }
57    }
58}
59pub trait VarToValue<T> {
60    fn to_val(&self) -> T;
61}
62#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Getters, WithSetters, Setters)]
63#[getset(get = "pub")]
64pub struct VarDefinition {
65    name: String,
66    value: ValueType,
67    #[getset(set_with = "pub")]
68    #[serde(
69        skip_serializing_if = "Option::is_none",
70        rename = "desc",
71        alias = "desp"
72    )]
73    desc: Option<String>,
74    #[getset(get = "pub", set_with = "pub", set = "pub")]
75    #[serde(default, skip)]
76    mutability: Mutability,
77}
78impl VarDefinition {
79    pub fn is_mutable(&self) -> bool {
80        match self.mutability {
81            Mutability::Immutable => false,
82            Mutability::System | Mutability::Module => true,
83        }
84    }
85    pub fn with_mut_immutable(mut self) -> Self {
86        self.mutability = Mutability::Immutable;
87        self
88    }
89    pub fn with_mut_system(mut self) -> Self {
90        self.mutability = Mutability::System;
91        self
92    }
93    pub fn with_mut_module(mut self) -> Self {
94        self.mutability = Mutability::Module;
95        self
96    }
97}
98
99impl VarDefinition {
100    /// 兼容旧 API:保留 `desp()` 访问器
101    #[deprecated(note = "renamed to desc()")]
102    pub fn desp(&self) -> &Option<String> {
103        self.desc()
104    }
105}
106impl From<(&str, &str)> for VarDefinition {
107    fn from(value: (&str, &str)) -> Self {
108        VarDefinition {
109            name: value.0.to_string(),
110            desc: None,
111            value: ValueType::from(value.1),
112            mutability: Mutability::default(),
113        }
114    }
115}
116impl From<(&str, bool)> for VarDefinition {
117    fn from(value: (&str, bool)) -> Self {
118        VarDefinition {
119            name: value.0.to_string(),
120            desc: None,
121            value: ValueType::from(value.1),
122            mutability: Mutability::default(),
123        }
124    }
125}
126impl From<(&str, u64)> for VarDefinition {
127    fn from(value: (&str, u64)) -> Self {
128        VarDefinition {
129            name: value.0.to_string(),
130            desc: None,
131            value: ValueType::from(value.1),
132            mutability: Mutability::default(),
133        }
134    }
135}
136impl From<(&str, f64)> for VarDefinition {
137    fn from(value: (&str, f64)) -> Self {
138        VarDefinition {
139            name: value.0.to_string(),
140            desc: None,
141            value: ValueType::from(value.1),
142            mutability: Mutability::default(),
143        }
144    }
145}
146
147impl From<(&str, ValueType)> for VarDefinition {
148    fn from(value: (&str, ValueType)) -> Self {
149        VarDefinition {
150            name: value.0.to_string(),
151            desc: None,
152            value: value.1,
153            mutability: Mutability::default(),
154        }
155    }
156}
157
158#[cfg(test)]
159mod tests {
160    use super::*;
161
162    #[test]
163    fn test_change_scope_factory_methods() {
164        assert_eq!(Mutability::immutable(), Mutability::Immutable);
165        assert_eq!(Mutability::system(), Mutability::System);
166        assert_eq!(Mutability::module(), Mutability::Module);
167    }
168
169    #[test]
170    fn test_change_scope_from_immutable_flag() {
171        assert_eq!(
172            Mutability::from_immutable_flag(Some(true)),
173            Mutability::Immutable
174        );
175        assert_eq!(
176            Mutability::from_immutable_flag(Some(false)),
177            Mutability::System
178        );
179        assert_eq!(Mutability::from_immutable_flag(None), Mutability::System);
180    }
181
182    #[test]
183    fn test_change_scope_to_immutable_flag() {
184        assert_eq!(Mutability::Immutable.to_immutable_flag(), Some(true));
185        assert_eq!(Mutability::System.to_immutable_flag(), Some(false));
186        assert_eq!(Mutability::Module.to_immutable_flag(), Some(false));
187    }
188
189    #[test]
190    fn test_var_definition_is_mutable() {
191        let immutable_var = VarDefinition {
192            name: "test".to_string(),
193            desc: None,
194            value: ValueType::from("value"),
195            mutability: Mutability::Immutable,
196        };
197        assert!(!immutable_var.is_mutable());
198
199        let public_var = VarDefinition {
200            name: "test".to_string(),
201            desc: None,
202            value: ValueType::from("value"),
203            mutability: Mutability::System,
204        };
205        assert!(public_var.is_mutable());
206
207        let model_var = VarDefinition {
208            name: "test".to_string(),
209            desc: None,
210            value: ValueType::from("value"),
211            mutability: Mutability::Module,
212        };
213        assert!(model_var.is_mutable());
214    }
215
216    #[test]
217    fn test_var_definition_from_tuple() {
218        let var = VarDefinition::from(("test_name", "test_value"));
219        assert_eq!(var.name(), "test_name");
220        assert_eq!(var.value(), &ValueType::from("test_value"));
221        assert_eq!(var.mutability(), &Mutability::Module);
222        assert!(var.is_mutable());
223    }
224
225    #[test]
226    fn test_var_definition_scope_getter_setter() {
227        let mut var = VarDefinition::from(("test", "value"));
228        assert_eq!(var.mutability(), &Mutability::Module);
229
230        var = var.with_mutability(Mutability::Immutable);
231        assert_eq!(var.mutability(), &Mutability::Immutable);
232        assert!(!var.is_mutable());
233
234        var = var.with_mutability(Mutability::Module);
235        assert_eq!(var.mutability(), &Mutability::Module);
236        assert!(var.is_mutable());
237    }
238
239    #[test]
240    fn test_var_definition_serialization() {
241        let var = VarDefinition {
242            name: "test".to_string(),
243            desc: None,
244            value: ValueType::from("value"),
245            mutability: Mutability::System,
246        };
247
248        // scope 应该被跳过序列化
249        let json = serde_json::to_string(&var).unwrap();
250        assert!(!json.contains("scope"));
251
252        // Non-Default scope 应该被序列化
253        let var_immutable = VarDefinition {
254            name: "test".to_string(),
255            desc: None,
256            value: ValueType::from("value"),
257            mutability: Mutability::Immutable,
258        };
259
260        let json_immutable = serde_json::to_string(&var_immutable).unwrap();
261        assert!(!json_immutable.contains("scope"));
262    }
263}