use core::fmt::Debug;
use musli::de::PackDecoder;
use musli::{Decode, Decoder, Encode};
use crate::tag::Tag;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Typed<T> {
tag: Tag,
value: T,
}
impl<T> Typed<T> {
pub const fn new(tag: Tag, 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(Tag::decode)?;
let value = pack.next().and_then(T::decode)?;
Ok(Self { tag, value })
}
}
#[macro_export]
macro_rules! rt {
($enum:ident :: $variant:ident $($body:tt)?) => {
$crate::rt!($enum, $enum :: $variant $($body)*)
};
($struct:ident $($body:tt)?) => {
$crate::rt!($struct, $struct $($body)*)
};
($ty:ty, $expr:expr) => {{
let value: $ty = $expr;
let out = $crate::to_vec(&value).expect(concat!("wire: ", stringify!($ty), ": failed to encode"));
let decoded: $ty = $crate::from_slice(&out[..]).expect(concat!("wire: ", stringify!($ty), ": failed to decode"));
assert_eq!(decoded, $expr, concat!("wire: ", stringify!($ty), ": roundtrip does not match"));
decoded
}};
}
#[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
}