settingsfile/structs/
types.rs1use std::collections::HashMap;
2use std::fmt;
3
4
5#[derive(Serialize,Deserialize,Debug,Clone,PartialEq)]
25#[serde(untagged)]
26pub enum Type {
27 Text(String),
28 Switch(bool),
29 Int(i32),
30 Float(f32),
31 Complex(HashMap<String,Type>),
32 Array(Vec<Type>),
33 None,
34}
35
36impl Type {
37 pub fn is_text(&self) -> bool { if let &Type::Text(_) = self { true } else { false } }
39 pub fn is_switch(&self) -> bool { if let &Type::Switch(_) = self { true } else { false } }
40 pub fn is_int(&self) -> bool { if let &Type::Int(_) = self { true } else { false } }
41 pub fn is_float(&self) -> bool { if let &Type::Float(_) = self { true } else { false } }
42 pub fn is_complex(&self) -> bool { if let &Type::Complex(_) = self { true } else { false } }
43 pub fn is_array(&self) -> bool { if let &Type::Array(_) = self { true } else { false } }
44 pub fn is_none(&self) -> bool { if let &Type::None = self { true } else { false } }
45
46 pub fn to_text(&self) -> Option<String> { if let &Type::Text(ref inner) = self { Some(inner.clone()) } else { None } }
49 pub fn to_switch(&self) -> Option<bool> { if let &Type::Switch(ref inner) = self { Some(inner.clone()) } else { None } }
50 pub fn to_int(&self) -> Option<i32> { if let &Type::Int(ref inner) = self { Some(inner.clone()) } else { None } }
51 pub fn to_float(&self) -> Option<f32> { if let &Type::Float(ref inner) = self { Some(inner.clone()) } else { None } }
52 pub fn to_complex(&self) -> Option<HashMap<String,Type>> { if let &Type::Complex(ref inner) = self { Some(inner.clone()) } else { None } }
53 pub fn to_array(&self) -> Option<Vec<Type>> { if let &Type::Array(ref inner) = self { Some(inner.clone()) } else { None } }
54
55 pub fn to_string(&self) -> String {
58 format!("{}",self)
59 }
60
61 pub fn flatten(&self , parent_key : Option<String>) -> Type {
62 match self {
72 &Type::Text(ref text) => Type::Text(text.clone()),
73 &Type::Switch(ref boolean) => Type::Switch(boolean.clone()),
74 &Type::Int(ref int) => Type::Int(int.clone()),
75 &Type::Float(ref float) => Type::Float(float.clone()),
76 &Type::Array(ref array) => Type::Array(array.clone()),
77 &Type::None => Type::None,
78 &Type::Complex(ref numb) => {
79 let mut flat : HashMap<String,Type> = HashMap::new();
80
81 for (key,value) in numb {
82 let parent = if let Some(ref parent_key) = parent_key {
83 format!("{}.{}",parent_key,key)
84 } else {
85 key.to_string()
86 };
87
88 let flattened = value.flatten(Some(parent.to_string()));
89
90 if flattened.is_complex() {
91 for (key,value) in flattened.to_complex().unwrap() {
92 flat.insert(key,value);
93 }
94 } else {
95 flat.insert(parent.to_string(),flattened);
96 }
97 }
98
99 Type::Complex(flat)
100 }
101 }
102 }
103}
104
105impl fmt::Display for Type {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 match self {
108 Type::Int(ref value) => write!(f,"{}",value),
109 Type::Switch(ref value) => write!(f,"{}",value),
110 Type::Float(ref value) => write!(f,"{}",value),
111 Type::Text(ref value) => write!(f,"{}",value),
112 Type::None => write!(f,"[BLANK]"),
113 Type::Array(ref value) => {
114 write!(f,"[ ")?;
115 for i in 0..value.len() {
116 write!(f,"{}",value[i])?;
117 if i < value.len() - 1 {
118 write!(f,", ")?;
119 }
120 }
121 write!(f," ]")
122 },
123 Type::Complex(ref value) => {
124 write!(f,"{{ ")?;
125 for (k,v) in value {
126 write!(f,"{} : {}, ", k,v)?;
127 }
128 write!(f," }}")
129 }
130 }
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use Type;
137 use std::collections::HashMap;
138
139 #[test]
140 fn flatten() {
141 let mut hash : HashMap<String,Type> = HashMap::new();
144 let mut hash2 : HashMap<String,Type> = HashMap::new();
145 hash2.insert("a".to_string(), Type::Switch(true));
146 hash2.insert("float".to_string(), Type::Float(10.23));
147 hash2.insert("int".to_string(), Type::Int(10));
148 hash2.insert("array".to_string(), Type::Array(vec![Type::Int(1), Type::Switch(false), Type::Text("testing here".to_string())]));
149
150 hash.insert("b".to_string(),Type::Complex(hash2));
151
152 let complex = Type::Complex(hash).flatten(None);
153
154 if let Type::Complex(ref stuff) = complex {
155 for (k,v) in stuff {
156 println!("{} : {:?}",k,v);
157 }
158 }
159
160 assert!(complex.to_complex().unwrap().get("b.a").unwrap().to_switch().unwrap());
161 assert!(complex.to_complex().unwrap().get("a") == None);
162 assert!(complex.to_complex().unwrap().get("b.int").unwrap().to_int().unwrap() == 10);
163 assert!(complex.to_complex().unwrap().get("b.float").unwrap().to_float().unwrap() == 10.23);
164 }
165
166 #[test]
167 fn display_print() {
168 let test1 = Type::Int(12);
169 let test2 = Type::Switch(false);
170 let test3 = Type::Float(12.01);
171 let test4 = Type::Text("Wjat os tjos".to_string());
172 let test5 = Type::Array(vec![ Type::Int(1),Type::Float(2.2) ]);
173
174 let mut hash : HashMap<String,Type> = HashMap::new();
175 hash.insert("1".to_string(),test1.clone());
176 hash.insert("2".to_string(),test2.clone());
177 hash.insert("3".to_string(),test3.clone());
178 hash.insert("4".to_string(),test4.clone());
179 hash.insert("5".to_string(),test5.clone());
180 let test6 = Type::Complex(hash);
181
182 println!("{}",test1);
183 println!("{}",test2);
184 println!("{}",test3);
185 println!("{}",test4);
186 println!("{}",test5);
187 println!("{}",test6);
188
189 assert!(true);
190 }
191}