1use crate::error::StructMapError;
2use std::collections::HashMap;
3use std::result::Result;
4use std::vec::Vec;
5pub use to_hash_map::*;
6
7#[derive(Debug, Clone)]
8pub enum FieldValue {
9 Null,
10 Bool(bool),
11 Int(i64),
12 Float(f64),
13 String(String),
14 Array(Vec<FieldValue>),
15 Map(HashMap<String, FieldValue>),
16}
17
18impl ToString for FieldValue {
19 fn to_string(&self) -> String {
20 match self {
21 FieldValue::Null => "".to_owned(),
22 FieldValue::Bool(value) => value.to_string(),
23 FieldValue::Int(value) => value.to_string(),
24 FieldValue::Float(value) => value.to_string(),
25 FieldValue::String(value) => value.to_string(),
26 FieldValue::Array(value) => {
27 let mut res = String::new();
28 for val in value.iter() {
29 let v = val.to_string();
30 res.push_str(v.as_str());
31 }
32 res
33 }
34 FieldValue::Map(value) => {
35 let mut res = String::new();
36 for (key, val) in value {
37 res.push_str(key.as_str());
38 let v = val.to_string();
39 res.push_str(v.as_str());
40 }
41 res
42 }
43 }
44 }
45}
46
47pub trait Converter: Sized {
48 fn to_field_value(&self) -> FieldValue;
49 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError>;
50}
51
52impl Converter for String {
53 fn to_field_value(&self) -> FieldValue {
54 FieldValue::String(self.to_string())
55 }
56 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
57 match fv {
58 FieldValue::String(value) => Ok(value),
59 _ => Err(StructMapError::new("invalid type: String")),
60 }
61 }
62}
63
64impl Converter for char {
65 fn to_field_value(&self) -> FieldValue {
66 FieldValue::String(self.to_string())
67 }
68 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
69 match fv {
70 FieldValue::String(value) => {
71 let chars: Vec<char> = value.chars().collect();
72 if chars.len() != 1 {
73 return Err(StructMapError::new("invalid type: char"));
74 }
75 Ok(chars[0])
76 }
77 _ => Err(StructMapError::new("invalid type: char")),
78 }
79 }
80}
81impl Converter for bool {
82 fn to_field_value(&self) -> FieldValue {
83 FieldValue::Bool(*self)
84 }
85
86 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
87 match fv {
88 FieldValue::Bool(value) => Ok(value),
89 _ => Err(StructMapError::new("invalid type: bool")),
90 }
91 }
92}
93
94macro_rules! integer_impls {
95 ($ ($type:ty) +) => {
96 $(
97 impl Converter for $type {
98 #[inline]
99 fn to_field_value(&self) -> FieldValue {
100 FieldValue::Int(*self as i64)
101 }
102
103 #[inline]
104 fn to_primitive(fv: FieldValue) ->Result<Self, StructMapError> {
105 match fv {
106 FieldValue::Int(value)=>{
107 if let Ok(value) = <$type>::try_from(value) {
108 return Ok(value);
109 }
110 return Err(StructMapError::new(format!("invalid type: {}",stringify!($type).to_owned())))
111 },
112 _=> Err(StructMapError::new(format!("invalid type: {}",stringify!($type).to_owned()))),
113 }
114 }
115 }
116 )+
117 }
118}
119
120integer_impls!(i8 i16 i32 i64 isize u8 u16 u32);
121
122impl Converter for f32 {
123 fn to_field_value(&self) -> FieldValue {
124 FieldValue::Float(*self as f64)
125 }
126 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
127 match fv {
128 FieldValue::Float(value) => Ok(value as f32),
129 _ => Err(StructMapError::new("invalid type: f32")),
130 }
131 }
132}
133
134impl Converter for f64 {
135 fn to_field_value(&self) -> FieldValue {
136 FieldValue::Float(*self)
137 }
138 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
139 match fv {
140 FieldValue::Float(value) => Ok(value),
141 _ => Err(StructMapError::new("invalid type: f64")),
142 }
143 }
144}
145
146impl<T> Converter for Option<T>
147where
148 T: Converter,
149{
150 fn to_field_value(&self) -> FieldValue {
151 match self {
152 Some(some) => some.to_field_value(),
153 None => FieldValue::Null,
154 }
155 }
156
157 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
158 match fv {
159 FieldValue::Null => Ok(None),
160 _ => Ok(Some(T::to_primitive(fv)?)),
161 }
162 }
163}
164
165impl<T> Converter for Vec<T>
166where
167 T: Converter,
168{
169 fn to_field_value(&self) -> FieldValue {
170 FieldValue::Array(self.iter().map(|v| v.to_field_value()).collect())
171 }
172
173 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
174 match fv {
175 FieldValue::Array(value) => value
176 .into_iter()
177 .map(|v| T::to_primitive(v))
178 .collect::<Result<Vec<T>, StructMapError>>(),
179 _ => Err(StructMapError::new("invalid type: Vec<T>")),
180 }
181 }
182}
183
184impl<K, V> Converter for HashMap<K, V>
185where
186 K: ToString + From<String> + std::cmp::Eq + std::hash::Hash,
187 V: Converter,
188{
189 fn to_field_value(&self) -> FieldValue {
190 FieldValue::Map(
191 self.iter()
192 .map(|(key, value)| (key.to_string(), value.to_field_value()))
193 .collect(),
194 )
195 }
196
197 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
198 match fv {
199 FieldValue::Map(value) => {
200 let mut result = HashMap::with_capacity(value.len());
201 for (k, v) in value {
202 if let Ok(k) = K::try_from(k) {
203 result.insert(k, V::to_primitive(v)?);
204 } else {
205 return Err(StructMapError::new("invalid type: HashMap<K, V>"));
206 }
207 }
208 Ok(result)
209 }
210 _ => Err(StructMapError::new("invalid type: HashMap<K, V>")),
211 }
212 }
213}
214
215pub trait ToHashMap {
216 fn to_map(&self) -> HashMap<String, FieldValue>;
217 fn from_map(map: HashMap<String, FieldValue>) -> Result<Self, StructMapError>
218 where
219 Self: std::marker::Sized;
220}
221
222impl<T> Converter for T
223where
224 T: ToHashMap,
225{
226 fn to_field_value(&self) -> FieldValue {
227 FieldValue::Map(self.to_map())
228 }
229
230 fn to_primitive(fv: FieldValue) -> Result<Self, StructMapError> {
231 match fv {
232 FieldValue::Map(value) => Ok(T::from_map(value)?),
233 _ => Err(StructMapError::new("invalid type: Mapper")),
234 }
235 }
236}