sppparse/
sparsable.rs

1use super::*;
2use std::collections::*;
3use std::ffi::CString;
4
5#[cfg(feature = "url")]
6use url_inner::Url;
7
8#[cfg(feature = "semver")]
9use semver_inner::{Version, VersionReq};
10
11/// # Implements base to be parsed by [Sparse](crate)
12pub trait Sparsable {
13    /// Initialize recusively a [Sparsable](Sparsable) pointer
14    fn sparse_init(
15        &mut self,
16        state: &mut SparseState,
17        metadata: &SparseMetadata,
18        depth: u32,
19    ) -> Result<(), SparseError>;
20
21    /// Update recusively a [Sparsable](Sparsable) pointer
22    fn sparse_updt(
23        &mut self,
24        state: &mut SparseState,
25        metadata: &SparseMetadata,
26        depth: u32,
27    ) -> Result<(), SparseError> {
28        self.sparse_init(state, metadata, depth)
29    }
30
31    /// Check if the current depth isn't too much.
32    /// This is the cyclic pointer protection mechanism
33    fn check_depth(&self, depth: u32) -> Result<(), SparseError> {
34        match depth < MAX_SPARSE_DEPTH {
35            true => Ok(()),
36            false => Err(SparseError::CyclicRef),
37        }
38    }
39}
40
41macro_rules! impl_sparsable_nothing {
42    ($x:ident) => {
43        impl Sparsable for $x {
44            fn sparse_init(
45                &mut self,
46                _state: &mut SparseState,
47                _metadata: &SparseMetadata,
48                _depth: u32,
49            ) -> Result<(), SparseError> {
50                Ok(())
51            }
52        }
53    };
54}
55
56#[cfg(feature = "url")]
57impl Sparsable for Url {
58    fn sparse_init(
59        &mut self,
60        _state: &mut SparseState,
61        _metadata: &SparseMetadata,
62        _depth: u32,
63    ) -> Result<(), SparseError> {
64        Ok(())
65    }
66}
67
68#[cfg(feature = "semver")]
69impl Sparsable for Version {
70    fn sparse_init(
71        &mut self,
72        _state: &mut SparseState,
73        _metadata: &SparseMetadata,
74        _depth: u32,
75    ) -> Result<(), SparseError> {
76        Ok(())
77    }
78}
79
80#[cfg(feature = "semver")]
81impl Sparsable for VersionReq {
82    fn sparse_init(
83        &mut self,
84        _state: &mut SparseState,
85        _metadata: &SparseMetadata,
86        _depth: u32,
87    ) -> Result<(), SparseError> {
88        Ok(())
89    }
90}
91
92impl Sparsable for serde_json::Value {
93    fn sparse_init(
94        &mut self,
95        _state: &mut SparseState,
96        _metadata: &SparseMetadata,
97        _depth: u32,
98    ) -> Result<(), SparseError> {
99        Ok(())
100    }
101}
102
103impl<T> Sparsable for Option<T>
104where
105    T: Serialize + DeserializeOwned + SparsableTrait,
106{
107    fn sparse_init(
108        &mut self,
109        state: &mut SparseState,
110        metadata: &SparseMetadata,
111        depth: u32,
112    ) -> Result<(), SparseError> {
113        match self {
114            Some(x) => x.sparse_init(state, metadata, depth + 1)?,
115            None => (),
116        };
117        Ok(())
118    }
119
120    fn sparse_updt(
121        &mut self,
122        state: &mut SparseState,
123        metadata: &SparseMetadata,
124        depth: u32,
125    ) -> Result<(), SparseError> {
126        match self {
127            Some(x) => x.sparse_updt(state, metadata, depth + 1)?,
128            None => (),
129        };
130        Ok(())
131    }
132}
133
134impl<'a> Sparsable for &'a str {
135    fn sparse_init(
136        &mut self,
137        _state: &mut SparseState,
138        _metadata: &SparseMetadata,
139        _depth: u32,
140    ) -> Result<(), SparseError> {
141        Ok(())
142    }
143}
144
145impl<'a> Sparsable for &'a [u8] {
146    fn sparse_init(
147        &mut self,
148        _state: &mut SparseState,
149        _metadata: &SparseMetadata,
150        _depth: u32,
151    ) -> Result<(), SparseError> {
152        Ok(())
153    }
154}
155
156impl<K, V> Sparsable for HashMap<K, V>
157where
158    V: Sparsable,
159{
160    fn sparse_init(
161        &mut self,
162        state: &mut SparseState,
163        metadata: &SparseMetadata,
164        depth: u32,
165    ) -> Result<(), SparseError> {
166        let ndepth = depth + 1;
167        for i in self.values_mut() {
168            i.sparse_init(state, metadata, ndepth)?;
169        }
170        Ok(())
171    }
172}
173
174macro_rules! impl_sparsable_iter {
175    ($x:ident) => {
176        impl<T> Sparsable for $x<T>
177        where
178            T: Sparsable,
179        {
180            fn sparse_init(
181                &mut self,
182                state: &mut SparseState,
183                metadata: &SparseMetadata,
184                depth: u32,
185            ) -> Result<(), SparseError> {
186                let ndepth = depth + 1;
187                for i in self.iter_mut() {
188                    i.sparse_init(state, metadata, ndepth)?;
189                }
190                Ok(())
191            }
192        }
193    };
194}
195
196impl_sparsable_nothing!(bool);
197impl_sparsable_nothing!(i8);
198impl_sparsable_nothing!(i16);
199impl_sparsable_nothing!(i32);
200impl_sparsable_nothing!(i64);
201impl_sparsable_nothing!(isize);
202impl_sparsable_nothing!(u8);
203impl_sparsable_nothing!(u16);
204impl_sparsable_nothing!(u32);
205impl_sparsable_nothing!(u64);
206impl_sparsable_nothing!(i128);
207impl_sparsable_nothing!(usize);
208impl_sparsable_nothing!(f32);
209impl_sparsable_nothing!(f64);
210impl_sparsable_nothing!(char);
211impl_sparsable_nothing!(String);
212impl_sparsable_nothing!(CString);
213impl_sparsable_iter!(Vec);
214impl_sparsable_iter!(VecDeque);
215impl_sparsable_iter!(LinkedList);