use anyhow::Result;
use core::fmt::Debug;
use musli::de::PackDecoder;
use musli::{Decode, Decoder, Encode};
use crate::types::TypeTag;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Typed<T> {
tag: TypeTag,
value: T,
}
impl<T> Typed<T> {
pub const fn new(tag: TypeTag, value: T) -> Self {
Self { tag, value }
}
}
impl<'de, T> Decode<'de> for Typed<T>
where
T: Decode<'de>,
{
fn decode<D>(decoder: D) -> Result<Self, D::Error>
where
D: Decoder<'de>,
{
let mut pack = decoder.decode_pack()?;
let tag = pack.next().and_then(TypeTag::decode)?;
let value = pack.next().and_then(T::decode)?;
Ok(Self { tag, value })
}
}
#[inline(never)]
pub fn rt<T>(expected: T) -> T
where
T: Debug + PartialEq + for<'de> Decode<'de> + Encode,
{
let out = crate::to_vec(&expected).expect("failed to encode");
let mut buf = &out[..];
dbg!(buf);
let value: T = crate::decode(&mut buf).expect("failed to decode");
assert!(buf.is_empty(), "deserialized buffer should be empty");
assert_eq!(value, expected, "roundtrip does not match");
value
}
#[inline(never)]
pub fn transcode<T, O>(value: T) -> O
where
T: Debug + PartialEq + Encode,
O: for<'de> Decode<'de>,
{
let out = crate::to_vec(&value).expect("failed to encode");
let mut buf = &out[..];
let value: O = crate::decode(&mut buf).expect("failed to decode");
assert!(buf.is_empty());
value
}