easy-sql-macros 1.1.2

Easy SQL support library
Documentation
use anyhow::Context;
use easy_macros::always_context;
use proc_macro::TokenStream;
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::{Ident, LitInt, Token, Type};

struct ImplSupportsFnAnyInput {
    driver: Type,
    target_trait: Ident,
}

impl Parse for ImplSupportsFnAnyInput {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let driver: Type = input.parse()?;
        input.parse::<Token![,]>()?;
        let target = input.parse()?;
        Ok(Self {
            driver,
            target_trait: target,
        })
    }
}

struct ImplSupportsFnInput {
    driver: Type,
    target: Ident,
    args: Vec<LitInt>,
}

impl Parse for ImplSupportsFnInput {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let driver: Type = input.parse()?;
        input.parse::<Token![,]>()?;
        let target = input.parse()?;
        let mut args = Vec::new();

        if !input.is_empty() {
            input.parse::<Token![,]>()?;
            while !input.is_empty() {
                let arg: LitInt = input.parse()?;
                args.push(arg);
                if input.is_empty() {
                    break;
                }
                input.parse::<Token![,]>()?;
            }
        }

        if args.is_empty() {
            return Err(input.error("Expected at least one argument count"));
        }

        Ok(Self {
            driver,
            target,
            args,
        })
    }
}

#[always_context]
pub fn impl_supports_fn_any(input: TokenStream) -> anyhow::Result<TokenStream> {
    let input: ImplSupportsFnAnyInput = syn::parse(input.clone())?;
    let sql_crate = crate::sql_crate();
    let driver = input.driver;

    let trait_ident = input.target_trait;

    let expanded = quote! {
        impl<const ARGS: isize> #sql_crate::markers::functions::#trait_ident<ARGS> for #driver {}
    };

    Ok(expanded.into())
}

#[always_context]
pub fn impl_supports_fn(input: TokenStream) -> anyhow::Result<TokenStream> {
    let input: ImplSupportsFnInput = syn::parse(input.clone())?;
    let sql_crate = crate::sql_crate();
    let driver = input.driver;
    let trait_ident = input.target;
    let args = input.args;

    let expanded = quote! {
        #(
            impl #sql_crate::markers::functions::#trait_ident<#args> for #driver {}
        )*
    };

    Ok(expanded.into())
}