binser-derive 0.2.0

Derive macros for binser.
Documentation
use proc_macro2::{Delimiter, Ident, Span, TokenStream, TokenTree};
use quote::{ToTokens, TokenStreamExt};
use syn::Attribute;

pub enum Repr {
    I8,
    U8,
    I16,
    U16,
    I32,
    U32,
    I64,
    U64,
}

impl Repr {
    pub fn parse(attrs: &[Attribute]) -> Result<Repr, &'static str> {
        let attr = attrs
            .iter()
            .find(|attr| attr.path.is_ident("repr"))
            .ok_or("no repr attribute has been found")?;

        let group = match attr.tokens.clone().into_iter().next() {
            Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Parenthesis => group,
            _ => return Err("expected a parenthesis delimited group group"),
        };

        let ident = match group.stream().into_iter().next() {
            Some(TokenTree::Ident(ident)) => ident,
            _ => return Err("expected an ident"),
        };

        let repr = match ident.to_string().as_str() {
            "i8" => Repr::I8,
            "u8" => Repr::U8,
            "i16" => Repr::I16,
            "u16" => Repr::U16,
            "i32" => Repr::I32,
            "u32" => Repr::U32,
            "i64" => Repr::I64,
            "u64" => Repr::U64,
            _ => return Err("invalid repr attribute"),
        };

        Ok(repr)
    }
}

impl ToTokens for Repr {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let ident = match self {
            Repr::I8 => "i8",
            Repr::U8 => "u8",
            Repr::I16 => "i16",
            Repr::U16 => "u16",
            Repr::I32 => "i32",
            Repr::U32 => "u32",
            Repr::I64 => "i64",
            Repr::U64 => "u64",
        };

        tokens.append(Ident::new(ident, Span::call_site()));
    }
}