seedle-macros 1.8.2

cbor codegeneration
Documentation
use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::Token;

struct Attr {
    pub ident: syn::Ident,
    pub _eq: syn::Token![=],
    pub val: syn::LitStr,
}

impl Parse for Attr {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(Attr {
            ident: input.parse()?,
            _eq: input.parse()?,
            val: input.parse()?,
        })
    }
}

// TODO redundant from parse crate
#[derive(Copy, Clone)]
pub enum Language {
    C,
    Rust,
    Typescript,
}
impl Default for Language {
    fn default() -> Self {
        Language::C
    }
}

impl From<syn::LitStr> for Language {
    fn from(value: syn::LitStr) -> Self {
        match value.value().as_str() {
            "ts" | "typescript" | "TYPESCRIPT" => Language::Typescript,
            "rs" | "rust" | "RUST" => Language::Rust,
            "c" | "C" => Language::C,
            _ => Language::default(),
        }
    }
}

#[derive(Default)]
pub struct Attributes {
    pub prefix: Option<syn::LitStr>,
    pub file: Option<syn::LitStr>,
    pub meta: Option<syn::LitStr>,
    pub language: Language,
}
impl Parse for Attributes {
    fn parse(i: ParseStream) -> Result<Self> {
        let p = Punctuated::<Attr, Token![,]>::parse_terminated_with(i, Attr::parse)?;
        let state = Attributes {
            ..Default::default()
        };
        let attrs = p.into_iter().fold(state, |mut state, attr| {
            if attr.ident == "prefix" {
                state.prefix = Some(attr.val);
            } else if attr.ident == "language" {
                state.language = attr.val.into()
            } else if attr.ident == "file" {
                state.file = Some(attr.val)
            } else if attr.ident == "meta" {
                state.meta = Some(attr.val)
            }
            state
        });
        Ok(attrs)
    }
}