hocon_rs/serde/
de.rs

1use std::cell::RefCell;
2
3use crate::merge::value::Value as MValue;
4use crate::value::Value;
5use serde::{
6    Deserializer,
7    de::{DeserializeSeed, IntoDeserializer, MapAccess, SeqAccess, Visitor},
8    forward_to_deserialize_any,
9};
10
11impl<'de> Deserializer<'de> for Value {
12    type Error = crate::error::Error;
13
14    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
15    where
16        V: Visitor<'de>,
17    {
18        match self {
19            Value::Null => visitor.visit_unit(),
20            Value::Boolean(b) => visitor.visit_bool(b),
21            Value::String(s) => visitor.visit_string(s),
22            Value::Number(n) => n
23                .deserialize_any(visitor)
24                .map_err(|e| crate::error::Error::Deserialize(e.to_string())),
25            Value::Array(arr) => {
26                struct SeqDeserializer {
27                    iter: std::vec::IntoIter<Value>,
28                }
29                impl<'de> SeqAccess<'de> for SeqDeserializer {
30                    type Error = crate::error::Error;
31                    fn next_element_seed<T>(
32                        &mut self,
33                        seed: T,
34                    ) -> Result<Option<T::Value>, Self::Error>
35                    where
36                        T: DeserializeSeed<'de>,
37                    {
38                        match self.iter.next() {
39                            Some(val) => seed.deserialize(val).map(Some),
40                            None => Ok(None),
41                        }
42                    }
43                }
44                visitor.visit_seq(SeqDeserializer {
45                    iter: arr.into_iter(),
46                })
47            }
48            Value::Object(map) => {
49                struct MapDeserializer {
50                    iter: std::collections::hash_map::IntoIter<String, Value>,
51                    value: Option<Value>,
52                }
53                impl<'de> MapAccess<'de> for MapDeserializer {
54                    type Error = crate::error::Error;
55                    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
56                    where
57                        K: DeserializeSeed<'de>,
58                    {
59                        match self.iter.next() {
60                            Some((k, v)) => {
61                                self.value = Some(v);
62                                seed.deserialize(k.into_deserializer()).map(Some)
63                            }
64                            None => Ok(None),
65                        }
66                    }
67                    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
68                    where
69                        V: DeserializeSeed<'de>,
70                    {
71                        seed.deserialize(self.value.take().unwrap())
72                    }
73                }
74                visitor.visit_map(MapDeserializer {
75                    iter: map.into_iter(),
76                    value: None,
77                })
78            }
79        }
80    }
81
82    // 我们只需要实现 `deserialize_any`,其他都用默认的转发实现即可
83    forward_to_deserialize_any! {
84        <W: Visitor<'de>>
85        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
86        bytes byte_buf option unit unit_struct newtype_struct seq tuple
87        tuple_struct map struct enum identifier ignored_any
88    }
89}
90
91impl<'de> Deserializer<'de> for MValue {
92    type Error = crate::error::Error;
93
94    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
95    where
96        V: Visitor<'de>,
97    {
98        match self {
99            MValue::Null | MValue::None => visitor.visit_unit(),
100            MValue::Boolean(b) => visitor.visit_bool(b),
101            MValue::String(s) => visitor.visit_string(s),
102            MValue::Number(n) => {
103                let n = n.deserialize_any(visitor)?;
104                Ok(n)
105            }
106            MValue::Array(arr) => {
107                struct SeqDeserializer {
108                    iter: std::vec::IntoIter<RefCell<MValue>>,
109                }
110                impl<'de> SeqAccess<'de> for SeqDeserializer {
111                    type Error = crate::error::Error;
112                    fn next_element_seed<T>(
113                        &mut self,
114                        seed: T,
115                    ) -> Result<Option<T::Value>, Self::Error>
116                    where
117                        T: DeserializeSeed<'de>,
118                    {
119                        match self.iter.next() {
120                            Some(val) => seed.deserialize(val.into_inner()).map(Some),
121                            None => Ok(None),
122                        }
123                    }
124                }
125                visitor.visit_seq(SeqDeserializer {
126                    iter: arr.into_inner().into_iter(),
127                })
128            }
129            MValue::Object(map) => {
130                struct MapDeserializer {
131                    iter: std::collections::btree_map::IntoIter<String, RefCell<MValue>>,
132                    value: Option<RefCell<MValue>>,
133                }
134                impl<'de> MapAccess<'de> for MapDeserializer {
135                    type Error = crate::error::Error;
136                    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
137                    where
138                        K: DeserializeSeed<'de>,
139                    {
140                        match self.iter.next() {
141                            Some((k, mut v)) => {
142                                if matches!(v.get_mut(), MValue::None) {
143                                    self.next_key_seed(seed)
144                                } else {
145                                    self.value = Some(v);
146                                    seed.deserialize(k.into_deserializer()).map(Some)
147                                }
148                            }
149                            None => Ok(None),
150                        }
151                    }
152                    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
153                    where
154                        V: DeserializeSeed<'de>,
155                    {
156                        seed.deserialize(self.value.take().unwrap().into_inner())
157                    }
158                }
159                visitor.visit_map(MapDeserializer {
160                    iter: map.into_inner().into_iter(),
161                    value: None,
162                })
163            }
164            MValue::Substitution(_)
165            | MValue::Concat(_)
166            | MValue::AddAssign(_)
167            | MValue::DelayReplacement(_) => Err(crate::error::Error::ResolveIncomplete),
168        }
169    }
170
171    forward_to_deserialize_any! {
172        <W: Visitor<'de>>
173        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
174        bytes byte_buf option unit unit_struct newtype_struct seq tuple
175        tuple_struct map struct enum identifier ignored_any
176    }
177}
178
179#[cfg(test)]
180mod tests {
181    use serde::Deserialize;
182
183    #[derive(Debug, Deserialize, Eq, PartialEq)]
184    struct Config {
185        app: App,
186        deployment: Deployment,
187    }
188
189    #[derive(Debug, Deserialize, Eq, PartialEq)]
190    struct App {
191        name: String,
192        version: String,
193        database: Database,
194        servers: Vec<Server>,
195        log_dir: String,
196        features: Features,
197    }
198
199    #[derive(Debug, Deserialize, Eq, PartialEq)]
200    struct Database {
201        host: String,
202        port: u16,
203        user: String,
204        password: String,
205        options: DatabaseOptions,
206    }
207
208    #[derive(Debug, Deserialize, Eq, PartialEq)]
209    struct DatabaseOptions {
210        ssl: bool,
211        timeout: u32,
212    }
213
214    #[derive(Debug, Deserialize, Eq, PartialEq)]
215    struct Server {
216        host: String,
217        roles: Vec<String>,
218    }
219
220    #[derive(Debug, Deserialize, Eq, PartialEq)]
221    struct Features {
222        experimental: bool,
223        max_connections: u32,
224        tags: Vec<String>,
225    }
226
227    #[derive(Debug, Deserialize, Eq, PartialEq)]
228    struct Deployment {
229        replicas: u32,
230        image: String,
231    }
232    #[test]
233    fn test_de() -> crate::Result<()> {
234        let config_hocon: Config = crate::config::Config::load("resources/deserialize.conf", None)?;
235        let file = std::fs::File::open("resources/deserialize.json").unwrap();
236        let config_json: Config = serde_json::from_reader(file)?;
237        assert_eq!(config_hocon, config_json);
238        Ok(())
239    }
240}