miniconf/
postcard.rs

1//! `TreeSerialize`/`TreeDeserialize` with `postcard`.
2//!
3//! ```
4//! use ::postcard::{de_flavors::Slice, ser_flavors::AllocVec};
5//! use miniconf::{postcard, Leaf, Packed, Tree, TreeKey};
6//!
7//! #[derive(Tree, Default, PartialEq, Debug)]
8//! struct S {
9//!     foo: Leaf<u32>,
10//!     bar: [Leaf<u16>; 2],
11//! };
12//!
13//! let source = S {
14//!     foo: 9.into(),
15//!     bar: [7.into(), 11.into()],
16//! };
17//! let kv: Vec<_> = S::nodes::<Packed, 2>()
18//!     .map(|p| {
19//!         let (p, _node) = p.unwrap();
20//!         let v = postcard::get_by_key(&source, p, AllocVec::new()).unwrap();
21//!         (p.into_lsb().get(), v)
22//!     })
23//!     .collect();
24//! assert_eq!(kv, [(2, vec![9]), (6, vec![7]), (7, vec![11])]);
25//!
26//! let mut target = S::default();
27//! for (k, v) in kv {
28//!     let p = Packed::from_lsb(k.try_into().unwrap());
29//!     postcard::set_by_key(&mut target, p, Slice::new(&v[..])).unwrap();
30//! }
31//! assert_eq!(source, target);
32//! ```
33
34use postcard::{de_flavors, ser_flavors, Deserializer, Serializer};
35
36use crate::{Error, IntoKeys, TreeDeserialize, TreeSerialize};
37
38/// Deserialize and set a node value from a `postcard` flavor.
39#[inline]
40pub fn set_by_key<
41    'de,
42    T: TreeDeserialize<'de> + ?Sized,
43    K: IntoKeys,
44    F: de_flavors::Flavor<'de>,
45>(
46    tree: &mut T,
47    keys: K,
48    flavor: F,
49) -> Result<F::Remainder, Error<postcard::Error>> {
50    let mut de = Deserializer::from_flavor(flavor);
51    tree.deserialize_by_key(keys.into_keys(), &mut de)?;
52    de.finalize().map_err(Error::Finalization)
53}
54
55/// Get and serialize a node value into a `postcard` flavor.
56#[inline]
57pub fn get_by_key<T: TreeSerialize + ?Sized, K: IntoKeys, F: ser_flavors::Flavor>(
58    tree: &T,
59    keys: K,
60    flavor: F,
61) -> Result<F::Output, Error<postcard::Error>> {
62    let mut ser = Serializer { output: flavor };
63    tree.serialize_by_key(keys.into_keys(), &mut ser)?;
64    ser.output.finalize().map_err(Error::Finalization)
65}