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, TreeSchema};
6//!
7//! #[derive(Tree, Default, PartialEq, Debug)]
8//! struct S {
9//! foo: u32,
10//! bar: [u16; 2],
11//! };
12//!
13//! let source = S {
14//! foo: 9,
15//! bar: [7, 11],
16//! };
17//! let kv: Vec<_> = S::SCHEMA.nodes::<Packed, 2>()
18//! .map(|p| {
19//! let p = 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::{Deserializer, Serializer, de_flavors, ser_flavors};
35
36use crate::{IntoKeys, SerdeError, TreeDeserialize, TreeSerialize};
37
38/// Deserialize and set a node value from a `postcard` flavor.
39pub fn set_by_key<'de, F: de_flavors::Flavor<'de>>(
40 tree: &mut (impl TreeDeserialize<'de> + ?Sized),
41 keys: impl IntoKeys,
42 flavor: F,
43) -> Result<F::Remainder, SerdeError<postcard::Error>> {
44 let mut de = Deserializer::from_flavor(flavor);
45 tree.deserialize_by_key(keys.into_keys(), &mut de)?;
46 de.finalize().map_err(SerdeError::Finalization)
47}
48
49/// Get and serialize a node value into a `postcard` flavor.
50pub fn get_by_key<F: ser_flavors::Flavor>(
51 tree: &(impl TreeSerialize + ?Sized),
52 keys: impl IntoKeys,
53 flavor: F,
54) -> Result<F::Output, SerdeError<postcard::Error>> {
55 let mut ser = Serializer { output: flavor };
56 tree.serialize_by_key(keys.into_keys(), &mut ser)?;
57 ser.output.finalize().map_err(SerdeError::Finalization)
58}