diff --git a/CHANGELOG.md b/CHANGELOG.md index f7a75c3d..06ffed1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -* `std` and `alloc` features and `Tree*` impls for `Box`, `Rc`, `Arc`, `Cow`, `Mutex`, - `RwLock`, `Cell`, `RefCell` +* `std` and `alloc` features and `Tree*` impls for `Box`, `Rc`, `RcWeak`, `Arc`, `ArcWeak`, + `Cow`, `Mutex`, `RwLock`, `Cell`, `RefCell`, `Bound` ## [0.17.0](https://github.com/quartiq/miniconf/compare/v0.16.3...v0.17.0) - 2024-10-25 diff --git a/miniconf/src/impls.rs b/miniconf/src/impls.rs index 6c400e61..18a9d94c 100644 --- a/miniconf/src/impls.rs +++ b/miniconf/src/impls.rs @@ -1,4 +1,5 @@ use core::cell::{Cell, RefCell}; +use core::ops::Bound; use core::{any::Any, num::NonZero}; use serde::{Deserializer, Serializer}; @@ -242,7 +243,7 @@ impl TreeAny for Option { ///////////////////////////////////////////////////////////////////////////////////////// const RESULT_LOOKUP: KeyLookup = KeyLookup { - len: NonZero::::MIN.saturating_add(1), + len: NonZero::::MIN.saturating_add(1), // 2 names: Some(&["Ok", "Err"]), }; @@ -328,6 +329,92 @@ impl TreeAny for Result { ///////////////////////////////////////////////////////////////////////////////////////// +const BOUND_LOOKUP: KeyLookup = KeyLookup { + len: NonZero::::MIN.saturating_add(1), + names: Some(&["Included", "Excluded"]), +}; + +impl TreeKey for Bound { + #[inline] + fn traverse_all() -> Result { + W::internal() + .merge(&T::traverse_all()?, Some(0), &BOUND_LOOKUP)? + .merge(&T::traverse_all()?, Some(1), &BOUND_LOOKUP) + } + + #[inline] + fn traverse_by_key(mut keys: K, func: F) -> Result> + where + K: Keys, + F: FnMut(usize, Option<&'static str>, NonZero) -> Result<(), G>, + { + Error::increment_result(match keys.next(&BOUND_LOOKUP)? { + 0..=1 => T::traverse_by_key(keys, func), + _ => unreachable!(), + }) + } +} + +impl TreeSerialize for Bound { + #[inline] + fn serialize_by_key(&self, mut keys: K, ser: S) -> Result> + where + K: Keys, + S: Serializer, + { + Error::increment_result(match (keys.next(&BOUND_LOOKUP)?, self) { + (0, Self::Included(value)) | (1, Self::Excluded(value)) => { + value.serialize_by_key(keys, ser) + } + _ => Err(Traversal::Absent(0).into()), + }) + } +} + +impl<'de, T: TreeDeserialize<'de>> TreeDeserialize<'de> for Bound { + #[inline] + fn deserialize_by_key(&mut self, mut keys: K, de: D) -> Result> + where + K: Keys, + D: Deserializer<'de>, + { + Error::increment_result(match (keys.next(&BOUND_LOOKUP)?, self) { + (0, Self::Included(value)) | (1, Self::Excluded(value)) => { + value.deserialize_by_key(keys, de) + } + _ => Err(Traversal::Absent(0).into()), + }) + } +} + +impl TreeAny for Bound { + #[inline] + fn ref_any_by_key(&self, mut keys: K) -> Result<&dyn Any, Traversal> + where + K: Keys, + { + match (keys.next(&BOUND_LOOKUP)?, self) { + (0, Self::Included(value)) | (1, Self::Excluded(value)) => value.ref_any_by_key(keys), + _ => Err(Traversal::Absent(0)), + } + .map_err(Traversal::increment) + } + + #[inline] + fn mut_any_by_key(&mut self, mut keys: K) -> Result<&mut dyn Any, Traversal> + where + K: Keys, + { + match (keys.next(&BOUND_LOOKUP)?, self) { + (0, Self::Included(value)) | (1, Self::Excluded(value)) => value.mut_any_by_key(keys), + _ => Err(Traversal::Absent(0)), + } + .map_err(Traversal::increment) + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + impl TreeKey for Cell { #[inline] fn traverse_all() -> Result {