Skip to content

Commit

Permalink
impls: add Box, Rc, Arc with std/alloc features
Browse files Browse the repository at this point in the history
close #237
  • Loading branch information
jordens committed Nov 12, 2024
1 parent 9de87e5 commit 963f6c2
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased](https://github.com/quartiq/miniconf/compare/v0.17.0...HEAD) - DATE

### Added

* `std` and `alloc` features and `Tree*` impls for `Box`, `Rc`, `Arc`

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

### Changed
Expand Down
2 changes: 2 additions & 0 deletions miniconf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ default = ["derive"]
json-core = ["dep:serde-json-core"]
postcard = ["dep:postcard"]
derive = ["dep:miniconf_derive", "serde/derive"]
alloc = []
std = ["alloc"]

[package.metadata.docs.rs]
all-features = true
Expand Down
2 changes: 1 addition & 1 deletion miniconf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ for path in Settings::nodes::<Path<heapless::String<32>, '/'>, 6>() {
match json::get(&settings, &path, &mut buf) {
// Full round-trip: deserialize and set again
Ok(len) => { json::set(&mut settings, &path, &buf[..len])?; }
// Some leaves are still `None` and thus their paths are expected to be absent
// Some Options are `None`, some enum variants are absent
Err(Error::Traversal(Traversal::Absent(_))) => {}
e => { e.unwrap(); }
}
Expand Down
193 changes: 193 additions & 0 deletions miniconf/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,196 @@ impl<T: TreeAny> TreeAny for Option<T> {
}

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

#[cfg(feature = "alloc")]
mod alloc {
use super::*;
extern crate alloc;
use alloc::{boxed::Box, rc::Rc};

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

#[inline]
fn traverse_by_key<K, F, E>(keys: K, func: F) -> Result<usize, Error<E>>
where
K: Keys,
F: FnMut(usize, Option<&'static str>, NonZero<usize>) -> Result<(), E>,
{
T::traverse_by_key(keys, func)
}
}

impl<T: TreeSerialize> TreeSerialize for Box<T> {
#[inline]
fn serialize_by_key<K, S>(&self, keys: K, ser: S) -> Result<usize, Error<S::Error>>
where
K: Keys,
S: Serializer,
{
(**self).serialize_by_key(keys, ser)
}
}

impl<'de, T: TreeDeserialize<'de>> TreeDeserialize<'de> for Box<T> {
#[inline]
fn deserialize_by_key<K, D>(&mut self, keys: K, de: D) -> Result<usize, Error<D::Error>>
where
K: Keys,
D: Deserializer<'de>,
{
(**self).deserialize_by_key(keys, de)
}
}

impl<T: TreeAny> TreeAny for Box<T> {
#[inline]
fn ref_any_by_key<K>(&self, keys: K) -> Result<&dyn Any, Traversal>
where
K: Keys,
{
(**self).ref_any_by_key(keys)
}

#[inline]
fn mut_any_by_key<K>(&mut self, keys: K) -> Result<&mut dyn Any, Traversal>
where
K: Keys,
{
(**self).mut_any_by_key(keys)
}
}

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

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

#[inline]
fn traverse_by_key<K, F, E>(keys: K, func: F) -> Result<usize, Error<E>>
where
K: Keys,
F: FnMut(usize, Option<&'static str>, NonZero<usize>) -> Result<(), E>,
{
T::traverse_by_key(keys, func)
}
}

impl<T: TreeSerialize> TreeSerialize for Rc<T> {
#[inline]
fn serialize_by_key<K, S>(&self, keys: K, ser: S) -> Result<usize, Error<S::Error>>
where
K: Keys,
S: Serializer,
{
(**self).serialize_by_key(keys, ser)
}
}

impl<'de, T: TreeDeserialize<'de>> TreeDeserialize<'de> for Rc<T> {
#[inline]
fn deserialize_by_key<K, D>(&mut self, keys: K, de: D) -> Result<usize, Error<D::Error>>
where
K: Keys,
D: Deserializer<'de>,
{
Rc::get_mut(self)
.ok_or(Traversal::Access(0, "Reference is taken"))?
.deserialize_by_key(keys, de)
}
}

impl<T: TreeAny> TreeAny for Rc<T> {
#[inline]
fn ref_any_by_key<K>(&self, keys: K) -> Result<&dyn Any, Traversal>
where
K: Keys,
{
(**self).ref_any_by_key(keys)
}

#[inline]
fn mut_any_by_key<K>(&mut self, keys: K) -> Result<&mut dyn Any, Traversal>
where
K: Keys,
{
Rc::get_mut(self)
.ok_or(Traversal::Access(0, "Reference is taken"))?
.mut_any_by_key(keys)
}
}
}

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

#[cfg(feature = "std")]
mod sync {
use super::*;
use std::sync::Arc;

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

#[inline]
fn traverse_by_key<K, F, E>(keys: K, func: F) -> Result<usize, Error<E>>
where
K: Keys,
F: FnMut(usize, Option<&'static str>, NonZero<usize>) -> Result<(), E>,
{
T::traverse_by_key(keys, func)
}
}

impl<T: TreeSerialize> TreeSerialize for Arc<T> {
#[inline]
fn serialize_by_key<K, S>(&self, keys: K, ser: S) -> Result<usize, Error<S::Error>>
where
K: Keys,
S: Serializer,
{
(**self).serialize_by_key(keys, ser)
}
}

impl<'de, T: TreeDeserialize<'de>> TreeDeserialize<'de> for Arc<T> {
#[inline]
fn deserialize_by_key<K, D>(&mut self, keys: K, de: D) -> Result<usize, Error<D::Error>>
where
K: Keys,
D: Deserializer<'de>,
{
Arc::get_mut(self)
.ok_or(Traversal::Access(0, "Reference is taken"))?
.deserialize_by_key(keys, de)
}
}

impl<T: TreeAny> TreeAny for Arc<T> {
#[inline]
fn ref_any_by_key<K>(&self, keys: K) -> Result<&dyn Any, Traversal>
where
K: Keys,
{
(**self).ref_any_by_key(keys)
}

#[inline]
fn mut_any_by_key<K>(&mut self, keys: K) -> Result<&mut dyn Any, Traversal>
where
K: Keys,
{
Arc::get_mut(self)
.ok_or(Traversal::Access(0, "Reference is taken"))?
.mut_any_by_key(keys)
}
}
}
2 changes: 1 addition & 1 deletion miniconf/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![no_std]
#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![doc = include_str!("../README.md")]
#![deny(rust_2018_compatibility)]
#![deny(rust_2018_idioms)]
Expand Down

0 comments on commit 963f6c2

Please sign in to comment.