architect-derive 0.4.0

Architect.xyz Trading Platform API, proc-macros
Documentation
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 {
                // this will never fail
                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)
}