minicbor-adapters 0.0.8

Adapters between `minicbor` and other crates such as `heapless` and `cboritem`
Documentation
//! Traits and functions through which this crate's encode and decode wrappers are implemented.
//!
//! While the traits are not sealed, there is little point in implementing them: If you'd consider
//! implementing them, just implement the equivalent trait from `heapless`.
//!
//! The traits are mainly public to give access to the list of foreign types on which they are
//! implemented.
//!
//! (There is *one* exception: If a variant of `minicbor-derive` were written that assigns this
//! crate as the default handler for `with`, then this crate can be extended to also cover all
//! `std`/`core` types, but third party types that would previously have implemented minicbor
//! traits will need to implement the traits here).
//!
//! # Usage example
//!
//! ```
//! use minicbor::*;
//! use cbor_macro::cbor;
//! use cboritem::CborItem;
//! #[derive(Decode, CborLen)]
//! struct IncompletelyDecoded<'a> {
//!     #[n(0)]
//!     x: u32,
//!     #[cbor(n(1), with = "minicbor_adapters")]
//!     y: heapless::String<4>,
//!     #[cbor(b(2), with = "minicbor_adapters")]
//!     z: CborItem<'a>,
//! };
//! let encoded = cbor!([23, "six", {"key": [1, 2, 3], "key2": "value2"}]);
//! let decoded: IncompletelyDecoded = minicbor::decode(&encoded).unwrap();
//! assert_eq!(decoded.x, 23);
//! assert_eq!(decoded.z, cbor!({"key": [1, 2, 3], "key2": "value2"}));
//! // This is particularly speed-up-py for complexly valued CborItems
//! assert_eq!(decoded.cbor_len(&mut ()), encoded.len());
//! ```

/// Function that can be used with minicbor's `cbor(decode_with=…)` or `cbor(with=…)` derive macro
/// argument.
///
/// Use like this:
///
/// ```
/// use minicbor::Decode;
///
/// #[derive(Decode, Debug)]
/// struct MyItem {
///     #[cbor(n(0), decode_with = "minicbor_adapters::decode")]
///     text: heapless::String<4>,
///     #[cbor(n(1), with = "minicbor_adapters")]
///     items: heapless::Vec<bool, 4>,
/// }
///
/// use cbor_macro::cbor;
///
/// let working = cbor!(["Hi", [false, true]]);
/// let parsed: MyItem = minicbor::decode(&working).unwrap();
/// assert_eq!(parsed.text, "Hi");
/// assert_eq!(parsed.items, [false, true]);
///
/// let too_long = cbor!(["Hello" / 5 bytes is more than 4 bytes /, []]);
/// let erred: Result<MyItem, _> = minicbor::decode(&too_long);
/// erred.unwrap_err();
/// ```
pub fn decode<'b, Ctx, T: OurDecode<'b, Ctx>>(
    d: &mut minicbor::Decoder<'b>,
    ctx: &mut Ctx,
) -> Result<T, minicbor::decode::Error> {
    T::decode(d, ctx)
}

/// Function that can be used with minicbor's `cbor(encode_with=…)` or `cbor(with=…)` derive macro
/// argument.
///
/// Use like this:
///
/// ```
/// use minicbor::Encode;
///
/// #[derive(Encode, Debug)]
/// struct MyItem {
///     #[cbor(n(0), encode_with = "minicbor_adapters::encode")]
///     text: heapless::String<4>,
///     #[cbor(n(1), with = "minicbor_adapters")]
///     items: heapless::Vec<bool, 4>,
/// }
///
/// let item = MyItem {
///     text: heapless::String::try_from("Hi").unwrap(),
///     items: heapless::Vec::try_from([true, false].as_slice()).unwrap(),
/// };
/// let mut buffer = [0u8; 128];
/// minicbor::encode(item, buffer.as_mut()).unwrap();
/// use cbor_macro::cbor;
/// let reference = cbor!(["Hi", [true, false]]);
/// assert_eq!(&buffer[..reference.len()], *reference);
/// ```
pub fn encode<Ctx, T: OurEncode<Ctx>, W: minicbor::encode::Write>(
    v: &T,
    e: &mut minicbor::encode::Encoder<W>,
    ctx: &mut Ctx,
) -> Result<(), minicbor::encode::Error<W::Error>> {
    T::encode(v, e, ctx)
}

/// This function enables deriving [`minicbor::CborLen`] in addition to [`minicbor::Encode`].
///
/// Use like this:
///
/// ```
/// use minicbor::{Encode, CborLen};
///
/// #[derive(Encode, CborLen, Debug)]
/// struct MyItem {
///     #[cbor(n(0), with = "minicbor_adapters")]
///     text: heapless::String<4>,
///     #[cbor(n(1), with = "minicbor_adapters")]
///     items: heapless::Vec<bool, 4>,
/// }
///
/// let item = MyItem {
///     text: heapless::String::try_from("Hi").unwrap(),
///     items: heapless::Vec::try_from([true, false].as_slice()).unwrap(),
/// };
/// let length = CborLen::cbor_len(&item, &mut ());
/// use cbor_macro::cbor;
/// let reference = cbor!(["Hi", [true, false]]);
/// assert_eq!(length, reference.len());
/// ```
pub fn cbor_len<Ctx, T: OurCborLen<Ctx>>(val: &T, ctx: &mut Ctx) -> usize {
    T::cbor_len(val, ctx)
}

/// Proxy trait for [`minicbor::Decode`]; see module level documentation.
///
/// This type is documented to give access to the list of types on which it is implemented.
pub trait OurDecode<'b, C>: Sized {
    fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error>;
}

/// Proxy trait for [`minicbor::Encode`]; see module level documentation.
///
/// This type is documented to give access to the list of types on which it is implemented.
pub trait OurEncode<C> {
    fn encode<W: minicbor::encode::Write>(
        &self,
        e: &mut minicbor::Encoder<W>,
        ctx: &mut C,
    ) -> Result<(), minicbor::encode::Error<W::Error>>;
}

/// Proxy trait for [`minicbor::CborLen`]; see module level documentation.
///
/// This type is documented to give access to the list of types on which it is implemented.
pub trait OurCborLen<C> {
    fn cbor_len(&self, ctx: &mut C) -> usize;
}