serde_lite/
update.rs

1use std::{
2    borrow::{Borrow, Cow},
3    cell::RefCell,
4    collections::HashMap,
5    hash::Hash,
6    ops::DerefMut,
7    rc::Rc,
8    sync::{Arc, Mutex},
9};
10
11use crate::{Deserialize, Error, Intermediate};
12
13/// Update trait.
14///
15/// The trait can be used for objects that can be updated from the intermediate
16/// representation.
17pub trait Update: Deserialize {
18    /// Update the object.
19    fn update(&mut self, val: &Intermediate) -> Result<(), Error>;
20}
21
22macro_rules! update_by_replace {
23    ( $x:ty ) => {
24        impl Update for $x {
25            #[inline]
26            fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
27                *self = <$x as Deserialize>::deserialize(val)?;
28
29                Ok(())
30            }
31        }
32    };
33}
34
35update_by_replace!(bool);
36
37update_by_replace!(i8);
38update_by_replace!(i16);
39update_by_replace!(i32);
40update_by_replace!(i64);
41update_by_replace!(i128);
42update_by_replace!(isize);
43
44update_by_replace!(u8);
45update_by_replace!(u16);
46update_by_replace!(u32);
47update_by_replace!(u64);
48update_by_replace!(u128);
49update_by_replace!(usize);
50
51update_by_replace!(f32);
52update_by_replace!(f64);
53
54update_by_replace!(char);
55
56update_by_replace!(String);
57
58impl<T> Update for Option<T>
59where
60    T: Update,
61{
62    #[inline]
63    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
64        if val.is_none() {
65            *self = None;
66        } else if let Some(inner) = self {
67            T::update(inner, val)?;
68        } else {
69            *self = T::deserialize(val).map(Some)?;
70        }
71
72        Ok(())
73    }
74}
75
76impl<T> Update for Vec<T>
77where
78    T: Update,
79{
80    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
81        if let Some(val) = val.as_array() {
82            match val.len() {
83                len if self.len() > len => self.truncate(len),
84                len if self.len() < len => self.reserve(len - self.len()),
85                _ => (),
86            }
87
88            for (index, elem) in val.iter().enumerate() {
89                if let Some(current) = self.get_mut(index) {
90                    current.update(elem)?;
91                } else {
92                    self.push(T::deserialize(elem)?);
93                }
94            }
95
96            Ok(())
97        } else {
98            Err(Error::invalid_value_static("array"))
99        }
100    }
101}
102
103impl<T> Update for [T; 0] {
104    #[inline]
105    fn update(&mut self, _: &Intermediate) -> Result<(), Error> {
106        Ok(())
107    }
108}
109
110macro_rules! update_array {
111    ( $len:expr => ($($n:tt)+) ) => {
112        impl<T> Update for [T; $len]
113        where
114            T: Update,
115        {
116            fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
117                if let Some(val) = val.as_array() {
118                    if val.len() < $len {
119                        return Err(Error::invalid_value_static(concat!(
120                            "an array of length ",
121                            $len
122                        )));
123                    }
124
125                    for (index, elem) in val.iter().enumerate() {
126                        self[index].update(elem)?;
127                    }
128
129                    Ok(())
130                } else {
131                    Err(Error::invalid_value_static(concat!(
132                        "an array of length ",
133                        $len
134                    )))
135                }
136            }
137        }
138    };
139}
140
141update_array!(1 => (0));
142update_array!(2 => (0 1));
143update_array!(3 => (0 1 2));
144update_array!(4 => (0 1 2 3));
145update_array!(5 => (0 1 2 3 4));
146update_array!(6 => (0 1 2 3 4 5));
147update_array!(7 => (0 1 2 3 4 5 6));
148update_array!(8 => (0 1 2 3 4 5 6 7));
149update_array!(9 => (0 1 2 3 4 5 6 7 8));
150update_array!(10 => (0 1 2 3 4 5 6 7 8 9));
151update_array!(11 => (0 1 2 3 4 5 6 7 8 9 10));
152update_array!(12 => (0 1 2 3 4 5 6 7 8 9 10 11));
153update_array!(13 => (0 1 2 3 4 5 6 7 8 9 10 11 12));
154update_array!(14 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13));
155update_array!(15 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14));
156update_array!(16 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15));
157update_array!(17 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16));
158update_array!(18 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17));
159update_array!(19 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18));
160update_array!(20 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19));
161update_array!(21 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20));
162update_array!(22 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21));
163update_array!(23 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22));
164update_array!(24 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23));
165update_array!(25 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24));
166update_array!(26 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25));
167update_array!(27 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26));
168update_array!(28 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27));
169update_array!(29 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28));
170update_array!(30 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29));
171update_array!(31 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30));
172update_array!(32 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31));
173
174impl Update for () {
175    #[inline]
176    fn update(&mut self, _: &Intermediate) -> Result<(), Error> {
177        Ok(())
178    }
179}
180
181macro_rules! update_tuple {
182    ( $len:expr => ($($n:tt $ty:ident)+) ) => {
183        impl<$($ty),+> Update for ($($ty,)+)
184        where
185            $($ty: Update,)+
186        {
187            fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
188                if let Some(val) = val.as_array() {
189                    if val.len() < $len {
190                        return Err(Error::invalid_value_static(concat!("an array of length ", $len)));
191                    }
192
193                    $(
194                        self.$n.update(&val[$n])?;
195                    )+
196
197                    Ok(())
198                } else {
199                    Err(Error::invalid_value_static(concat!("an array of length ", $len)))
200                }
201            }
202        }
203    };
204}
205
206update_tuple!(1 => (0 T0));
207update_tuple!(2 => (0 T0 1 T1));
208update_tuple!(3 => (0 T0 1 T1 2 T2));
209update_tuple!(4 => (0 T0 1 T1 2 T2 3 T3));
210update_tuple!(5 => (0 T0 1 T1 2 T2 3 T3 4 T4));
211update_tuple!(6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5));
212update_tuple!(7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6));
213update_tuple!(8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7));
214update_tuple!(9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8));
215update_tuple!(10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9));
216update_tuple!(11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10));
217update_tuple!(12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11));
218update_tuple!(13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12));
219update_tuple!(14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13));
220update_tuple!(15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14));
221update_tuple!(16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15));
222
223impl<K, V> Update for HashMap<K, V>
224where
225    K: From<Cow<'static, str>> + Borrow<str> + Eq + Hash,
226    V: Update,
227{
228    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
229        let val = val
230            .as_map()
231            .ok_or_else(|| Error::invalid_value_static("map"))?;
232
233        for (name, value) in val {
234            if let Some(inner) = self.get_mut(name) {
235                V::update(inner, value)?;
236            } else {
237                let k = K::from(name.clone());
238                let v = V::deserialize(value)?;
239
240                self.insert(k, v);
241            }
242        }
243
244        Ok(())
245    }
246}
247
248#[cfg(feature = "preserve-order")]
249impl<K, V> Update for indexmap::IndexMap<K, V>
250where
251    K: From<Cow<'static, str>> + Borrow<str> + Eq + Hash,
252    V: Update,
253{
254    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
255        let val = val
256            .as_map()
257            .ok_or_else(|| Error::invalid_value_static("map"))?;
258
259        for (name, value) in val {
260            if let Some(inner) = self.get_mut(name as &str) {
261                V::update(inner, value)?;
262            } else {
263                let k = K::from(name.clone());
264                let v = V::deserialize(value)?;
265
266                self.insert(k, v);
267            }
268        }
269
270        Ok(())
271    }
272}
273
274impl<T> Update for Box<T>
275where
276    T: Update,
277{
278    #[inline]
279    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
280        self.deref_mut().update(val)
281    }
282}
283
284impl<T> Update for Mutex<T>
285where
286    T: Update,
287{
288    #[inline]
289    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
290        self.get_mut().unwrap().update(val)
291    }
292}
293
294impl<T> Update for Arc<Mutex<T>>
295where
296    T: Update,
297{
298    #[inline]
299    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
300        self.lock().unwrap().update(val)
301    }
302}
303
304impl<T> Update for RefCell<T>
305where
306    T: Update,
307{
308    #[inline]
309    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
310        self.borrow_mut().update(val)
311    }
312}
313
314impl<T> Update for Rc<RefCell<T>>
315where
316    T: Update,
317{
318    #[inline]
319    fn update(&mut self, val: &Intermediate) -> Result<(), Error> {
320        self.borrow_mut().update(val)
321    }
322}