miniconf/impls/
leaves.rs

1use core::{
2    any::Any,
3    fmt::Display,
4    ops::{Deref, DerefMut},
5};
6
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8
9use crate::{
10    Keys, Schema, SerdeError, TreeAny, TreeDeserialize, TreeSchema, TreeSerialize, ValueError,
11};
12
13/// Passthrough Tree*
14pub mod passthrough {
15    use super::*;
16
17    /// [`TreeSerialize::serialize_by_key()`]
18    #[inline]
19    pub fn serialize_by_key<T: TreeSerialize + ?Sized, S: Serializer>(
20        value: &T,
21        keys: impl Keys,
22        ser: S,
23    ) -> Result<S::Ok, SerdeError<S::Error>> {
24        value.serialize_by_key(keys, ser)
25    }
26
27    /// [`TreeDeserialize::deserialize_by_key()`]
28    #[inline]
29    pub fn deserialize_by_key<'de, T: TreeDeserialize<'de> + ?Sized, D: Deserializer<'de>>(
30        value: &mut T,
31        keys: impl Keys,
32        de: D,
33    ) -> Result<(), SerdeError<D::Error>> {
34        value.deserialize_by_key(keys, de)
35    }
36
37    /// [`TreeDeserialize::probe_by_key()`]
38    #[inline]
39    pub fn probe_by_key<'de, T: TreeDeserialize<'de> + ?Sized, D: Deserializer<'de>>(
40        keys: impl Keys,
41        de: D,
42    ) -> Result<(), SerdeError<D::Error>> {
43        T::probe_by_key(keys, de)
44    }
45
46    /// [`TreeAny::ref_any_by_key()`]
47    #[inline]
48    pub fn ref_any_by_key(value: &impl TreeAny, keys: impl Keys) -> Result<&dyn Any, ValueError> {
49        value.ref_any_by_key(keys)
50    }
51
52    /// [`TreeAny::mut_any_by_key()`]
53    #[inline]
54    pub fn mut_any_by_key(
55        value: &mut impl TreeAny,
56        keys: impl Keys,
57    ) -> Result<&mut dyn Any, ValueError> {
58        value.mut_any_by_key(keys)
59    }
60}
61
62/// Leaf implementation using serde::{Serialize, Deserialize}
63///
64/// To be used as a derive macros attribute `#[tree(with=leaf)]`.
65pub mod leaf {
66    use super::*;
67
68    /// [`TreeSchema::SCHEMA`]
69    pub const SCHEMA: &Schema = &Schema::LEAF;
70
71    /// [`TreeSerialize::serialize_by_key()`]
72    pub fn serialize_by_key<T: Serialize + ?Sized, S: Serializer>(
73        value: &T,
74        mut keys: impl Keys,
75        ser: S,
76    ) -> Result<S::Ok, SerdeError<S::Error>> {
77        keys.finalize()?;
78        Serialize::serialize(value, ser).map_err(SerdeError::Inner)
79    }
80
81    /// [`TreeDeserialize::deserialize_by_key()`]
82    pub fn deserialize_by_key<'de, T: Deserialize<'de>, D: Deserializer<'de>>(
83        value: &mut T,
84        mut keys: impl Keys,
85        de: D,
86    ) -> Result<(), SerdeError<D::Error>> {
87        keys.finalize()?;
88        Deserialize::deserialize_in_place(de, value).map_err(SerdeError::Inner)?;
89        Ok(())
90    }
91
92    /// [`TreeDeserialize::probe_by_key()`]
93    pub fn probe_by_key<'de, T: Deserialize<'de>, D: Deserializer<'de>>(
94        mut keys: impl Keys,
95        de: D,
96    ) -> Result<(), SerdeError<D::Error>> {
97        keys.finalize()?;
98        T::deserialize(de).map_err(SerdeError::Inner)?;
99        Ok(())
100    }
101
102    /// [`TreeAny::ref_any_by_key()`]
103    pub fn ref_any_by_key(value: &impl Any, mut keys: impl Keys) -> Result<&dyn Any, ValueError> {
104        keys.finalize()?;
105        Ok(value)
106    }
107
108    /// [`TreeAny::mut_any_by_key()`]
109    pub fn mut_any_by_key(
110        value: &mut impl Any,
111        mut keys: impl Keys,
112    ) -> Result<&mut dyn Any, ValueError> {
113        keys.finalize()?;
114        Ok(value)
115    }
116}
117
118/// `Serialize`/`Deserialize`/`Any` leaf
119///
120/// This wraps [`Serialize`], [`Deserialize`], and [`Any`] into `Tree` a leaf node.
121///
122/// ```
123/// use miniconf::{json_core, Leaf, Tree};
124/// let mut s = Leaf(0);
125/// json_core::set(&mut s, "", b"7").unwrap();
126/// assert!(matches!(*s, 7));
127/// ```
128#[derive(
129    Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize,
130)]
131#[serde(transparent)]
132#[repr(transparent)]
133pub struct Leaf<T: ?Sized>(pub T);
134
135impl<T: ?Sized> Deref for Leaf<T> {
136    type Target = T;
137    #[inline]
138    fn deref(&self) -> &Self::Target {
139        &self.0
140    }
141}
142
143impl<T: ?Sized> DerefMut for Leaf<T> {
144    #[inline]
145    fn deref_mut(&mut self) -> &mut Self::Target {
146        &mut self.0
147    }
148}
149
150impl<T: Display> Display for Leaf<T> {
151    #[inline]
152    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
153        self.0.fmt(f)
154    }
155}
156
157impl<T: ?Sized> TreeSchema for Leaf<T> {
158    const SCHEMA: &'static Schema = leaf::SCHEMA;
159}
160
161impl<T: Serialize + ?Sized> TreeSerialize for Leaf<T> {
162    #[inline]
163    fn serialize_by_key<S: Serializer>(
164        &self,
165        keys: impl Keys,
166        ser: S,
167    ) -> Result<S::Ok, SerdeError<S::Error>> {
168        leaf::serialize_by_key(&self.0, keys, ser)
169    }
170}
171
172impl<'de, T: Deserialize<'de>> TreeDeserialize<'de> for Leaf<T> {
173    #[inline]
174    fn deserialize_by_key<D: Deserializer<'de>>(
175        &mut self,
176        keys: impl Keys,
177        de: D,
178    ) -> Result<(), SerdeError<D::Error>> {
179        leaf::deserialize_by_key(&mut self.0, keys, de)
180    }
181
182    #[inline]
183    fn probe_by_key<D: Deserializer<'de>>(
184        keys: impl Keys,
185        de: D,
186    ) -> Result<(), SerdeError<D::Error>> {
187        leaf::probe_by_key::<T, _>(keys, de)
188    }
189}
190
191impl<T: Any> TreeAny for Leaf<T> {
192    #[inline]
193    fn ref_any_by_key(&self, keys: impl Keys) -> Result<&dyn Any, ValueError> {
194        leaf::ref_any_by_key(&self.0, keys)
195    }
196
197    #[inline]
198    fn mut_any_by_key(&mut self, keys: impl Keys) -> Result<&mut dyn Any, ValueError> {
199        leaf::mut_any_by_key(&mut self.0, keys)
200    }
201}
202
203/////////////////////////////////////////////////////////////////////////////////////////
204
205macro_rules! impl_leaf {
206    ($ty0:ty, $($ty:ty), +) => {
207        impl_leaf! {$ty0}
208        impl_leaf! {$($ty),+}
209    };
210    ($ty:ty) => {
211        impl TreeSchema for $ty {
212            const SCHEMA: &'static Schema = leaf::SCHEMA;
213        }
214
215        impl TreeSerialize for $ty {
216            #[inline]
217            fn serialize_by_key<S: Serializer>(
218                &self,
219                keys: impl Keys,
220                ser: S,
221            ) -> Result<S::Ok, SerdeError<S::Error>> {
222                leaf::serialize_by_key(self, keys, ser)
223            }
224        }
225
226        impl<'de> TreeDeserialize<'de> for $ty {
227            #[inline]
228            fn deserialize_by_key<D: Deserializer<'de>>(
229                &mut self,
230                keys: impl Keys,
231                de: D,
232            ) -> Result<(), SerdeError<D::Error>> {
233                leaf::deserialize_by_key(self, keys, de)
234            }
235
236            #[inline]
237            fn probe_by_key<D: Deserializer<'de>>(
238                keys: impl Keys,
239                de: D,
240            ) -> Result<(), SerdeError<D::Error>> {
241                leaf::probe_by_key::<Self, _>(keys, de)
242            }
243        }
244
245        impl TreeAny for $ty {
246            #[inline]
247            fn ref_any_by_key(&self, keys: impl Keys) -> Result<&dyn Any, ValueError> {
248                leaf::ref_any_by_key(self, keys)
249            }
250
251            #[inline]
252            fn mut_any_by_key(&mut self, keys: impl Keys) -> Result<&mut dyn Any, ValueError> {
253                leaf::mut_any_by_key(self, keys)
254            }
255        }
256    };
257}
258
259impl_leaf! {
260    (), bool, char, f32, f64,
261    i8, i16, i32, i64, i128, isize,
262    u8, u16, u32, u64, u128, usize
263}
264impl_leaf! {core::net::SocketAddr, core::net::SocketAddrV4, core::net::SocketAddrV6}
265impl_leaf! {core::time::Duration}
266
267macro_rules! impl_unsized_leaf {
268    ($ty:ty) => {
269        impl TreeSchema for $ty {
270            const SCHEMA: &'static Schema = leaf::SCHEMA;
271        }
272
273        impl TreeSerialize for $ty {
274            #[inline]
275            fn serialize_by_key<S: Serializer>(
276                &self,
277                keys: impl Keys,
278                ser: S,
279            ) -> Result<S::Ok, SerdeError<S::Error>> {
280                leaf::serialize_by_key(self, keys, ser)
281            }
282        }
283
284        impl<'a, 'de: 'a> TreeDeserialize<'de> for &'a $ty {
285            #[inline]
286            fn deserialize_by_key<D: Deserializer<'de>>(
287                &mut self,
288                keys: impl Keys,
289                de: D,
290            ) -> Result<(), SerdeError<D::Error>> {
291                leaf::deserialize_by_key(self, keys, de)
292            }
293
294            #[inline]
295            fn probe_by_key<D: Deserializer<'de>>(
296                keys: impl Keys,
297                de: D,
298            ) -> Result<(), SerdeError<D::Error>> {
299                leaf::probe_by_key::<Self, _>(keys, de)
300            }
301        }
302    };
303}
304
305impl_unsized_leaf! {str}
306impl_unsized_leaf! {[u8]}
307
308#[cfg(feature = "alloc")]
309impl_leaf! {String}
310
311#[cfg(feature = "std")]
312mod std_impls {
313    use super::*;
314
315    impl_leaf! {std::ffi::CString, std::ffi::OsString}
316    impl_leaf! {std::time::SystemTime}
317    impl_leaf! {std::path::PathBuf}
318    impl_unsized_leaf! {std::path::Path}
319
320    #[cfg(target_has_atomic = "8")]
321    impl_leaf! { core::sync::atomic::AtomicBool, core::sync::atomic::AtomicI8, core::sync::atomic::AtomicU8 }
322    #[cfg(target_has_atomic = "16")]
323    impl_leaf! { core::sync::atomic::AtomicI16, core::sync::atomic::AtomicU16 }
324    #[cfg(target_has_atomic = "32")]
325    impl_leaf! { core::sync::atomic::AtomicI32, core::sync::atomic::AtomicU32 }
326    #[cfg(target_has_atomic = "64")]
327    impl_leaf! { core::sync::atomic::AtomicI64, core::sync::atomic::AtomicU64 }
328}
329
330#[cfg(feature = "heapless")]
331mod heapless_impls {
332    use super::*;
333
334    use heapless::{String, Vec};
335
336    impl<const N: usize> TreeSchema for String<N> {
337        const SCHEMA: &'static Schema = leaf::SCHEMA;
338    }
339
340    impl<const N: usize> TreeSerialize for String<N> {
341        #[inline]
342        fn serialize_by_key<S: Serializer>(
343            &self,
344            keys: impl Keys,
345            ser: S,
346        ) -> Result<S::Ok, SerdeError<S::Error>> {
347            leaf::serialize_by_key(self, keys, ser)
348        }
349    }
350
351    impl<'de, const N: usize> TreeDeserialize<'de> for String<N> {
352        #[inline]
353        fn deserialize_by_key<D: Deserializer<'de>>(
354            &mut self,
355            keys: impl Keys,
356            de: D,
357        ) -> Result<(), SerdeError<D::Error>> {
358            leaf::deserialize_by_key(self, keys, de)
359        }
360
361        #[inline]
362        fn probe_by_key<D: Deserializer<'de>>(
363            keys: impl Keys,
364            de: D,
365        ) -> Result<(), SerdeError<D::Error>> {
366            leaf::probe_by_key::<String<N>, _>(keys, de)
367        }
368    }
369
370    impl<const N: usize> TreeAny for String<N> {
371        #[inline]
372        fn ref_any_by_key(&self, keys: impl Keys) -> Result<&dyn Any, ValueError> {
373            leaf::ref_any_by_key(self, keys)
374        }
375
376        #[inline]
377        fn mut_any_by_key(&mut self, keys: impl Keys) -> Result<&mut dyn Any, ValueError> {
378            leaf::mut_any_by_key(self, keys)
379        }
380    }
381
382    impl<T, const N: usize> TreeSchema for Vec<T, N> {
383        const SCHEMA: &'static Schema = leaf::SCHEMA;
384    }
385
386    impl<T: Serialize, const N: usize> TreeSerialize for Vec<T, N> {
387        #[inline]
388        fn serialize_by_key<S: Serializer>(
389            &self,
390            keys: impl Keys,
391            ser: S,
392        ) -> Result<S::Ok, SerdeError<S::Error>> {
393            leaf::serialize_by_key(self, keys, ser)
394        }
395    }
396
397    impl<'de, T: Deserialize<'de>, const N: usize> TreeDeserialize<'de> for Vec<T, N> {
398        #[inline]
399        fn deserialize_by_key<D: Deserializer<'de>>(
400            &mut self,
401            keys: impl Keys,
402            de: D,
403        ) -> Result<(), SerdeError<D::Error>> {
404            leaf::deserialize_by_key(self, keys, de)
405        }
406
407        #[inline]
408        fn probe_by_key<D: Deserializer<'de>>(
409            keys: impl Keys,
410            de: D,
411        ) -> Result<(), SerdeError<D::Error>> {
412            leaf::probe_by_key::<String<N>, _>(keys, de)
413        }
414    }
415
416    impl<T: 'static, const N: usize> TreeAny for Vec<T, N> {
417        #[inline]
418        fn ref_any_by_key(&self, keys: impl Keys) -> Result<&dyn Any, ValueError> {
419            leaf::ref_any_by_key(self, keys)
420        }
421
422        #[inline]
423        fn mut_any_by_key(&mut self, keys: impl Keys) -> Result<&mut dyn Any, ValueError> {
424            leaf::mut_any_by_key(self, keys)
425        }
426    }
427}
428
429/// `TryFrom<&str>`/`AsRef<str>` leaf
430///
431/// This wraps [`TryFrom<&str>`] and [`AsRef<str>`] into a `Tree*` leaf.
432/// [`TreeAny`] is implemented but denied access at runtime.
433/// It is especially useful to support enum variant switching using `strum`.
434/// Inner enum variant field access can be implemented using `defer`.
435///
436/// ```
437/// use miniconf::{json_core::set, str_leaf, Tree};
438/// #[derive(Tree, strum::AsRefStr, strum::EnumString)]
439/// enum En {
440///     A(i32),
441///     B(f32),
442/// }
443/// #[derive(Tree)]
444/// struct S {
445///     #[tree(rename="t", with=str_leaf, defer=self.e, typ="En")]
446///     _t: (),
447///     e: En,
448/// }
449/// let mut s = S {
450///     _t: (),
451///     e: En::A(9),
452/// };
453/// set(&mut s, "/t", b"\"B\"").unwrap();
454/// set(&mut s, "/e/B", b"1.2").unwrap();
455/// assert!(matches!(s.e, En::B(1.2)));
456/// ```
457pub mod str_leaf {
458    use super::*;
459
460    pub use deny::{mut_any_by_key, ref_any_by_key};
461    pub use leaf::SCHEMA;
462
463    /// [`TreeSerialize::serialize_by_key()`]
464    #[inline]
465    pub fn serialize_by_key<S: Serializer>(
466        value: &(impl AsRef<str> + ?Sized),
467        mut keys: impl Keys,
468        ser: S,
469    ) -> Result<S::Ok, SerdeError<S::Error>> {
470        keys.finalize()?;
471        value.as_ref().serialize(ser).map_err(SerdeError::Inner)
472    }
473
474    /// [`TreeDeserialize::deserialize_by_key()`]
475    #[inline]
476    pub fn deserialize_by_key<'de, D: Deserializer<'de>>(
477        value: &mut impl TryFrom<&'de str>,
478        mut keys: impl Keys,
479        de: D,
480    ) -> Result<(), SerdeError<D::Error>> {
481        keys.finalize()?;
482        let name: &str = Deserialize::deserialize(de).map_err(SerdeError::Inner)?;
483        *value = name
484            .try_into()
485            .or(Err(ValueError::Access("Could not convert from str")))?;
486        Ok(())
487    }
488
489    /// [`TreeDeserialize::probe_by_key()`]
490    #[inline]
491    pub fn probe_by_key<'de, T: TryFrom<&'de str>, D: Deserializer<'de>>(
492        mut keys: impl Keys,
493        de: D,
494    ) -> Result<(), SerdeError<D::Error>> {
495        keys.finalize()?;
496        let name: &str = Deserialize::deserialize(de).map_err(SerdeError::Inner)?;
497        T::try_from(name).or(Err(ValueError::Access("Could not convert from str")))?;
498        Ok(())
499    }
500}
501
502/// Deny access tools.
503///
504/// These return early without consuming keys or finalizing them.
505pub mod deny {
506    use super::*;
507
508    pub use leaf::SCHEMA;
509
510    /// [`TreeSerialize::serialize_by_key()`]
511    #[inline]
512    pub fn serialize_by_key<S: Serializer>(
513        _value: &impl ?Sized,
514        _keys: impl Keys,
515        _ser: S,
516    ) -> Result<S::Ok, SerdeError<S::Error>> {
517        Err(ValueError::Access("Denied").into())
518    }
519
520    /// [`TreeDeserialize::deserialize_by_key()`]
521    #[inline]
522    pub fn deserialize_by_key<'de, D: Deserializer<'de>>(
523        _value: &mut impl ?Sized,
524        _keys: impl Keys,
525        _de: D,
526    ) -> Result<(), SerdeError<D::Error>> {
527        Err(ValueError::Access("Denied").into())
528    }
529
530    /// [`TreeDeserialize::probe_by_key()`]
531    #[inline]
532    pub fn probe_by_key<'de, T: ?Sized, D: Deserializer<'de>>(
533        _keys: impl Keys,
534        _de: D,
535    ) -> Result<(), SerdeError<D::Error>> {
536        Err(ValueError::Access("Denied").into())
537    }
538
539    /// [`TreeAny::ref_any_by_key()`]
540    #[inline]
541    pub fn ref_any_by_key(_value: &impl ?Sized, _keys: impl Keys) -> Result<&dyn Any, ValueError> {
542        Err(ValueError::Access("Denied"))
543    }
544
545    /// [`TreeAny::mut_any_by_key()`]
546    #[inline]
547    pub fn mut_any_by_key(
548        _value: &mut impl ?Sized,
549        _keys: impl Keys,
550    ) -> Result<&mut dyn Any, ValueError> {
551        Err(ValueError::Access("Denied"))
552    }
553}