use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, parse_quote, DeriveInput, GenericParam};
pub fn derive_from_value(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
for param in &mut input.generics.params {
if let GenericParam::Type(typ) = param {
typ.bounds.push(parse_quote!(netidx_core::pack::Pack));
typ.bounds.push(parse_quote!('static))
}
}
let name = input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let expanded = quote! {
impl #impl_generics Into<netidx::protocol::value::Value> for #name #ty_generics #where_clause {
fn into(self) -> netidx::protocol::value::Value {
netidx::protocol::value::Value::Bytes(
netidx::utils::pack(&self).unwrap().freeze(),
)
}
}
impl #impl_generics netidx::protocol::value::FromValue for #name #ty_generics #where_clause {
fn from_value(v: netidx::protocol::value::Value) -> anyhow::Result<Self> {
match v {
netidx::protocol::value::Value::Bytes(mut b) => {
Ok(netidx::pack::Pack::decode(&mut b)?)
}
_ => anyhow::bail!("invalid value, expected a bytes {:?}", v),
}
}
}
};
proc_macro::TokenStream::from(expanded)
}