Skip to content

Commit

Permalink
impls: Range*
Browse files Browse the repository at this point in the history
  • Loading branch information
jordens committed Nov 12, 2024
1 parent c80b95b commit fbbb17a
Show file tree
Hide file tree
Showing 2 changed files with 292 additions and 4 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,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`, `RcWeak`, `Arc`, `ArcWeak`,
`Cow`, `Mutex`, `RwLock`, `Cell`, `RefCell`, `Bound`
`Cow`, `Mutex`, `RwLock`, `Cell`, `RefCell`, `Bound`, `Range`, `RangeFrom`, `RangeTo`,
`RangeInflusive`

## [0.17.0](https://github.com/quartiq/miniconf/compare/v0.16.3...v0.17.0) - 2024-10-25

Expand Down
293 changes: 290 additions & 3 deletions miniconf/src/impls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::cell::{Cell, RefCell};
use core::ops::Bound;
use core::ops::{Bound, Range, RangeFrom, RangeInclusive, RangeTo};
use core::{any::Any, num::NonZero};

use serde::{Deserializer, Serializer};
Expand Down Expand Up @@ -337,9 +337,10 @@ const BOUND_LOOKUP: KeyLookup = KeyLookup {
impl<T: TreeKey> TreeKey for Bound<T> {
#[inline]
fn traverse_all<W: Walk>() -> Result<W, W::Error> {
let t = T::traverse_all()?;
W::internal()
.merge(&T::traverse_all()?, Some(0), &BOUND_LOOKUP)?
.merge(&T::traverse_all()?, Some(1), &BOUND_LOOKUP)
.merge(&t, Some(0), &BOUND_LOOKUP)?
.merge(&t, Some(1), &BOUND_LOOKUP)
}

#[inline]
Expand Down Expand Up @@ -415,6 +416,292 @@ impl<T: TreeAny> TreeAny for Bound<T> {

/////////////////////////////////////////////////////////////////////////////////////////

const RANGE_LOOKUP: KeyLookup = KeyLookup {
len: NonZero::<usize>::MIN.saturating_add(1),
names: Some(&["start", "end"]),
};

impl<T: TreeKey> TreeKey for Range<T> {
#[inline]
fn traverse_all<W: Walk>() -> Result<W, W::Error> {
let t = T::traverse_all()?;
W::internal()
.merge(&t, Some(0), &RANGE_LOOKUP)?
.merge(&t, Some(1), &RANGE_LOOKUP)
}

#[inline]
fn traverse_by_key<K, F, G>(mut keys: K, func: F) -> Result<usize, Error<G>>
where
K: Keys,
F: FnMut(usize, Option<&'static str>, NonZero<usize>) -> Result<(), G>,
{
Error::increment_result(match keys.next(&RANGE_LOOKUP)? {
0..=1 => T::traverse_by_key(keys, func),
_ => unreachable!(),
})
}
}

impl<T: TreeSerialize> TreeSerialize for Range<T> {
#[inline]
fn serialize_by_key<K, S>(&self, mut keys: K, ser: S) -> Result<usize, Error<S::Error>>
where
K: Keys,
S: Serializer,
{
Error::increment_result(match keys.next(&RANGE_LOOKUP)? {
0 => self.start.serialize_by_key(keys, ser),
1 => self.end.serialize_by_key(keys, ser),
_ => unreachable!(),
})
}
}

impl<'de, T: TreeDeserialize<'de>> TreeDeserialize<'de> for Range<T> {
#[inline]
fn deserialize_by_key<K, D>(&mut self, mut keys: K, de: D) -> Result<usize, Error<D::Error>>
where
K: Keys,
D: Deserializer<'de>,
{
Error::increment_result(match keys.next(&RANGE_LOOKUP)? {
0 => self.start.deserialize_by_key(keys, de),
1 => self.end.deserialize_by_key(keys, de),
_ => unreachable!(),
})
}
}

impl<T: TreeAny> TreeAny for Range<T> {
#[inline]
fn ref_any_by_key<K>(&self, mut keys: K) -> Result<&dyn Any, Traversal>
where
K: Keys,
{
match keys.next(&RANGE_LOOKUP)? {
0 => self.start.ref_any_by_key(keys),
1 => self.end.ref_any_by_key(keys),
_ => unreachable!(),
}
.map_err(Traversal::increment)
}

#[inline]
fn mut_any_by_key<K>(&mut self, mut keys: K) -> Result<&mut dyn Any, Traversal>
where
K: Keys,
{
match keys.next(&RANGE_LOOKUP)? {
0 => self.start.mut_any_by_key(keys),
1 => self.end.mut_any_by_key(keys),
_ => unreachable!(),
}
.map_err(Traversal::increment)
}
}

/////////////////////////////////////////////////////////////////////////////////////////

impl<T: TreeKey> TreeKey for RangeInclusive<T> {
#[inline]
fn traverse_all<W: Walk>() -> Result<W, W::Error> {
let t = T::traverse_all()?;
W::internal()
.merge(&t, Some(0), &RANGE_LOOKUP)?
.merge(&t, Some(1), &RANGE_LOOKUP)
}

#[inline]
fn traverse_by_key<K, F, G>(mut keys: K, func: F) -> Result<usize, Error<G>>
where
K: Keys,
F: FnMut(usize, Option<&'static str>, NonZero<usize>) -> Result<(), G>,
{
Error::increment_result(match keys.next(&RANGE_LOOKUP)? {
0..=1 => T::traverse_by_key(keys, func),
_ => unreachable!(),
})
}
}

impl<T: TreeSerialize> TreeSerialize for RangeInclusive<T> {
#[inline]
fn serialize_by_key<K, S>(&self, mut keys: K, ser: S) -> Result<usize, Error<S::Error>>
where
K: Keys,
S: Serializer,
{
Error::increment_result(match keys.next(&RANGE_LOOKUP)? {
0 => self.start().serialize_by_key(keys, ser),
1 => self.end().serialize_by_key(keys, ser),
_ => unreachable!(),
})
}
}

/////////////////////////////////////////////////////////////////////////////////////////

const RANGE_FROM_LOOKUP: KeyLookup = KeyLookup {
len: NonZero::<usize>::MIN,
names: Some(&["start"]),
};

impl<T: TreeKey> TreeKey for RangeFrom<T> {
#[inline]
fn traverse_all<W: Walk>() -> Result<W, W::Error> {
W::internal().merge(&T::traverse_all()?, Some(0), &RANGE_FROM_LOOKUP)
}

#[inline]
fn traverse_by_key<K, F, G>(mut keys: K, func: F) -> Result<usize, Error<G>>
where
K: Keys,
F: FnMut(usize, Option<&'static str>, NonZero<usize>) -> Result<(), G>,
{
Error::increment_result(match keys.next(&RANGE_FROM_LOOKUP)? {
0 => T::traverse_by_key(keys, func),
_ => unreachable!(),
})
}
}

impl<T: TreeSerialize> TreeSerialize for RangeFrom<T> {
#[inline]
fn serialize_by_key<K, S>(&self, mut keys: K, ser: S) -> Result<usize, Error<S::Error>>
where
K: Keys,
S: Serializer,
{
Error::increment_result(match keys.next(&RANGE_FROM_LOOKUP)? {
0 => self.start.serialize_by_key(keys, ser),
_ => unreachable!(),
})
}
}

impl<'de, T: TreeDeserialize<'de>> TreeDeserialize<'de> for RangeFrom<T> {
#[inline]
fn deserialize_by_key<K, D>(&mut self, mut keys: K, de: D) -> Result<usize, Error<D::Error>>
where
K: Keys,
D: Deserializer<'de>,
{
Error::increment_result(match keys.next(&RANGE_FROM_LOOKUP)? {
0 => self.start.deserialize_by_key(keys, de),
_ => unreachable!(),
})
}
}

impl<T: TreeAny> TreeAny for RangeFrom<T> {
#[inline]
fn ref_any_by_key<K>(&self, mut keys: K) -> Result<&dyn Any, Traversal>
where
K: Keys,
{
match keys.next(&RANGE_FROM_LOOKUP)? {
0 => self.start.ref_any_by_key(keys),
_ => unreachable!(),
}
.map_err(Traversal::increment)
}

#[inline]
fn mut_any_by_key<K>(&mut self, mut keys: K) -> Result<&mut dyn Any, Traversal>
where
K: Keys,
{
match keys.next(&RANGE_FROM_LOOKUP)? {
0 => self.start.mut_any_by_key(keys),
_ => unreachable!(),
}
.map_err(Traversal::increment)
}
}

/////////////////////////////////////////////////////////////////////////////////////////

const RANGE_TO_LOOKUP: KeyLookup = KeyLookup {
len: NonZero::<usize>::MIN,
names: Some(&["end"]),
};

impl<T: TreeKey> TreeKey for RangeTo<T> {
#[inline]
fn traverse_all<W: Walk>() -> Result<W, W::Error> {
W::internal().merge(&T::traverse_all()?, Some(0), &RANGE_TO_LOOKUP)
}

#[inline]
fn traverse_by_key<K, F, G>(mut keys: K, func: F) -> Result<usize, Error<G>>
where
K: Keys,
F: FnMut(usize, Option<&'static str>, NonZero<usize>) -> Result<(), G>,
{
Error::increment_result(match keys.next(&RANGE_TO_LOOKUP)? {
0 => T::traverse_by_key(keys, func),
_ => unreachable!(),
})
}
}

impl<T: TreeSerialize> TreeSerialize for RangeTo<T> {
#[inline]
fn serialize_by_key<K, S>(&self, mut keys: K, ser: S) -> Result<usize, Error<S::Error>>
where
K: Keys,
S: Serializer,
{
Error::increment_result(match keys.next(&RANGE_TO_LOOKUP)? {
0 => self.end.serialize_by_key(keys, ser),
_ => unreachable!(),
})
}
}

impl<'de, T: TreeDeserialize<'de>> TreeDeserialize<'de> for RangeTo<T> {
#[inline]
fn deserialize_by_key<K, D>(&mut self, mut keys: K, de: D) -> Result<usize, Error<D::Error>>
where
K: Keys,
D: Deserializer<'de>,
{
Error::increment_result(match keys.next(&RANGE_TO_LOOKUP)? {
0 => self.end.deserialize_by_key(keys, de),
_ => unreachable!(),
})
}
}

impl<T: TreeAny> TreeAny for RangeTo<T> {
#[inline]
fn ref_any_by_key<K>(&self, mut keys: K) -> Result<&dyn Any, Traversal>
where
K: Keys,
{
match keys.next(&RANGE_TO_LOOKUP)? {
0 => self.end.ref_any_by_key(keys),
_ => unreachable!(),
}
.map_err(Traversal::increment)
}

#[inline]
fn mut_any_by_key<K>(&mut self, mut keys: K) -> Result<&mut dyn Any, Traversal>
where
K: Keys,
{
match keys.next(&RANGE_TO_LOOKUP)? {
0 => self.end.mut_any_by_key(keys),
_ => unreachable!(),
}
.map_err(Traversal::increment)
}
}

/////////////////////////////////////////////////////////////////////////////////////////

impl<T: TreeKey> TreeKey for Cell<T> {
#[inline]
fn traverse_all<W: Walk>() -> Result<W, W::Error> {
Expand Down

0 comments on commit fbbb17a

Please sign in to comment.