ogma-macros 0.1.6

Ogma DSL builder libs
Documentation
use ogma_libs::clause::{parse, ParseError, Token};
use proc_macro2::TokenStream;
use quote::ToTokens;
use syn::parse::{Parse, ParseStream};
use syn::{
    punctuated::Punctuated,
    token::{Comma, Const, Eq, Semi},
    Error, Ident, LitStr, Visibility,
};

pub struct ClauseArgs {
    pub vis: Visibility,
    pub name: Ident,
    pub tokens: Punctuated<TokenOwned, Comma>,
}

pub enum TokenOwned {
    Static(String),
    QueryVar(String),
    DataVar(String),
}

impl<'a> From<Token<'a>> for TokenOwned {
    fn from(t: Token<'a>) -> Self {
        match t {
            Token::Static(s) => TokenOwned::Static(s.to_owned()),
            Token::QueryVar(s) => TokenOwned::QueryVar(s.to_owned()),
            Token::DataVar(s) => TokenOwned::DataVar(s.to_owned()),
        }
    }
}

impl ToTokens for TokenOwned {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        tokens.extend(match self {
            TokenOwned::Static(s) => quote! { ::ogma::clause::Token::Static(#s) },
            TokenOwned::QueryVar(s) => quote! { ::ogma::clause::Token::QueryVar(#s) },
            TokenOwned::DataVar(s) => quote! { ::ogma::clause::Token::DataVar(#s) },
        });
    }
}

impl Parse for ClauseArgs {
    fn parse(input: ParseStream) -> Result<Self, Error> {
        let vis = input.parse()?;
        let _ = input.parse::<Const>();
        let name = input.parse()?;
        let _ = input.parse::<Eq>()?;
        let clause_lit_str = input.parse::<LitStr>()?;
        let clause_str = clause_lit_str.value();
        let tokens = parse(&clause_str)
            .collect::<Result<Vec<Token>, ParseError>>()
            .map_err(|e| Error::new(clause_lit_str.span(), e))?
            .into_iter()
            .map(TokenOwned::from)
            .collect();
        let _ = input.parse::<Semi>();
        Ok(ClauseArgs { vis, name, tokens })
    }
}