use proc_macro2::TokenStream;
use syn::Result;
pub fn handle_manifest_decode(input: TokenStream) -> Result<TokenStream> {
sbor_derive_common::decode::handle_decode(
input,
Some("radix_common::data::manifest::ManifestCustomValueKind"),
)
}
#[cfg(test)]
mod tests {
use super::*;
use proc_macro2::TokenStream;
use quote::quote;
use std::str::FromStr;
fn assert_code_eq(a: TokenStream, b: TokenStream) {
assert_eq!(a.to_string(), b.to_string());
}
#[test]
fn test_decode_struct() {
let input = TokenStream::from_str("pub struct MyStruct { }").unwrap();
let output = handle_manifest_decode(input).unwrap();
assert_code_eq(
output,
quote! {
impl<D: sbor::Decoder<radix_common::data::manifest::ManifestCustomValueKind> >
sbor::Decode<radix_common::data::manifest::ManifestCustomValueKind, D> for MyStruct
{
#[inline]
fn decode_body_with_value_kind(
decoder: &mut D,
value_kind: sbor::ValueKind<radix_common::data::manifest::ManifestCustomValueKind>
) -> Result<Self, sbor::DecodeError> {
use sbor::{self, Decode};
decoder.check_preloaded_value_kind(value_kind, sbor::ValueKind::Tuple)?;
decoder.read_and_check_size(0usize)?;
Ok(Self {})
}
}
},
);
}
#[test]
fn test_decode_enum() {
let input = TokenStream::from_str("enum MyEnum<T: Bound> { A { named: T }, B(String), C }")
.unwrap();
let output = handle_manifest_decode(input).unwrap();
assert_code_eq(
output,
quote! {
impl<
T: Bound,
D: sbor::Decoder<radix_common::data::manifest::ManifestCustomValueKind>
> sbor::Decode<radix_common::data::manifest::ManifestCustomValueKind, D> for MyEnum<T>
where
T: sbor::Decode<radix_common::data::manifest::ManifestCustomValueKind, D>
{
#[inline]
fn decode_body_with_value_kind(
decoder: &mut D,
value_kind: sbor::ValueKind<radix_common::data::manifest::ManifestCustomValueKind>
) -> Result<Self, sbor::DecodeError> {
use sbor::{self, Decode};
decoder.check_preloaded_value_kind(value_kind, sbor::ValueKind::Enum)?;
let discriminator = decoder.read_discriminator()?;
#[deny(unreachable_patterns)]
match discriminator {
0u8 => {
decoder.read_and_check_size(1usize)?;
Ok(Self::A {
named: decoder.decode::<T>()?,
})
},
1u8 => {
decoder.read_and_check_size(1usize)?;
Ok(Self::B(decoder.decode::<String>()?,))
},
2u8 => {
decoder.read_and_check_size(0usize)?;
Ok(Self::C)
},
_ => Err(sbor::DecodeError::UnknownDiscriminator(discriminator))
}
}
}
},
);
}
}