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