sword-macros 0.2.1

Structured web framework built on top of tokio ecosystem, providing powerful features for building robust web applications.
Documentation
mod generation;

pub use generation::*;

use syn::{
    Expr, Path, Token,
    parse::{Parse, ParseStream},
};

pub enum InterceptorArgs {
    SwordSimple(Path),
    SwordWithConfig {
        middleware: Path,
        config: Expr,
    },
    /// Any expression (Tower layer or anything else)
    Expression(Expr),
}

impl Parse for InterceptorArgs {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        if let Some(result) = parse_as_sword_middleware(input)? {
            return Ok(result);
        }

        Ok(Self::Expression(input.parse()?))
    }
}

fn parse_as_sword_middleware(
    input: ParseStream,
) -> syn::Result<Option<InterceptorArgs>> {
    let fork = input.fork();

    let Ok(_) = fork.parse::<Path>() else {
        return Ok(None);
    };

    if fork.is_empty() {
        return Ok(Some(InterceptorArgs::SwordSimple(input.parse()?)));
    }

    if fork.peek(Token![,]) {
        let config_fork = fork;

        // Check , config = expr
        if config_fork.parse::<Token![,]>().is_ok()
            && config_fork.peek(syn::Ident)
            && config_fork.peek2(Token![=])
        {
            if let Ok(ident) = config_fork.parse::<syn::Ident>() {
                if ident == "config"
                    && config_fork.parse::<Token![=]>().is_ok()
                    && config_fork.parse::<Expr>().is_ok()
                {
                    let path: Path = input.parse()?;

                    input.parse::<Token![,]>()?; // ,
                    input.parse::<syn::Ident>()?; // config
                    input.parse::<Token![=]>()?; // =

                    return Ok(Some(InterceptorArgs::SwordWithConfig {
                        middleware: path,
                        config: input.parse()?,
                    }));
                }
            }
        }
    }

    Ok(None)
}