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 Immutable,
10 System,
12 #[default]
14 Module,
15}
16
17impl Mutability {
18 pub fn is_default(&self) -> bool {
20 matches!(self, Mutability::Module)
21 }
22
23 pub fn immutable() -> Self {
25 Mutability::Immutable
26 }
27
28 pub fn system() -> Self {
30 Mutability::System
31 }
32
33 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 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 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 #[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 let json = serde_json::to_string(&var).unwrap();
250 assert!(!json.contains("scope"));
251
252 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}