ts-sql-helper-derive 0.6.2

Derives for ts-sql-helper-lib
Documentation
use quote::{ToTokens, quote};
use syn::{
    Ident, LitInt, LitStr, Token, Type, braced, bracketed,
    parse::{Parse, ParseStream},
};

pub mod main_struct;
pub mod parameters;
pub mod row_struct;
pub mod test;

pub struct RowField {
    pub name: Ident,
    pub r#type: Type,
}
impl Parse for RowField {
    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
        let name: Ident = input.parse()?;
        input.parse::<Token![:]>()?;
        let r#type: Type = input.parse()?;

        Ok(Self { name, r#type })
    }
}
impl ToTokens for RowField {
    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
        let name = &self.name;
        let r#type = &self.r#type;
        let new_tokens = quote! {
            #name: #r#type
        };

        tokens.extend(new_tokens);
    }
}

pub struct QueryMacroInput {
    pub name: Ident,
    pub row: Option<Vec<RowField>>,
    pub optional_params: Option<Vec<usize>>,
    pub query: LitStr,
}
impl Parse for QueryMacroInput {
    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
        let name = {
            input.parse::<name_keyword::name>()?;
            input.parse::<Token![:]>()?;

            let name: Ident = input.parse()?;

            input.parse::<Token![,]>()?;

            name
        };

        let row = if input.peek(row_keyword::row) {
            input.parse::<row_keyword::row>()?;
            input.parse::<Token![:]>()?;

            let content;
            braced![content in input];
            let row: Vec<_> = content
                .parse_terminated(RowField::parse, Token![,])?
                .into_iter()
                .collect();

            input.parse::<Token![,]>()?;

            Some(row)
        } else {
            None
        };

        let optional_params = if input.peek(optional_params_keyword::optional_params) {
            input.parse::<optional_params_keyword::optional_params>()?;
            input.parse::<Token![:]>()?;

            let content;
            bracketed![content in input];
            let optional_params: Vec<_> = content
                .parse_terminated(LitInt::parse, Token![,])?
                .iter()
                .map(|v| v.base10_parse().unwrap())
                .collect();

            input.parse::<Token![,]>()?;

            Some(optional_params)
        } else {
            None
        };

        let query = {
            input.parse::<query_keyword::query>()?;
            input.parse::<Token![:]>()?;

            input.parse()?
        };

        Ok(Self {
            name,
            row,
            optional_params,
            query,
        })
    }
}

mod name_keyword {
    syn::custom_keyword!(name);
}
mod optional_params_keyword {
    syn::custom_keyword!(optional_params);
}
mod row_keyword {
    syn::custom_keyword!(row);
}
mod query_keyword {
    syn::custom_keyword!(query);
}