#syn #def #parser #parameters #arguments #array #string

syn-args

syn-args is a library for parsing function arguments

4 releases (2 breaking)

new 0.3.0 Aug 31, 2024
0.2.1 Aug 25, 2024
0.2.0 Aug 25, 2024
0.1.0 Aug 24, 2024

#255 in Development tools

Download history 218/week @ 2024-08-19 201/week @ 2024-08-26

419 downloads per month

MIT license

590KB
1K SLoC

⚙️ SynArgs

Repo Link · 中文文档

Hello

SynArgs is a powerful and easy-to-use string pattern matching and parsing tool that can parse strings into corresponding data structures. It is widely applicable to various parameter parsing needs and can be flexibly extended to suit complex parsing scenarios.

Focus

  • Easy to Use: Quickly get started and easily parse strings into structs.
  • Highly Extensible: Supports extended parameter definitions to adapt to various parsing scenarios.
  • Supports Multiple Basic Types: Built-in support for common basic types such as arrays, booleans, integers, etc.
  • Custom Type Support: Flexibly define and parse custom data structures.
  • Parameter Reset Matching: Achieve complex parameter resetting and matching through enum outputs.
  • Multiple Parameter Parsing Modes:
    • F(P1, P2)
    • (P1, P2)
    • P1, P2
  • Built on syn: Utilizes Rust's syn library for underlying parsing, ensuring stability and efficiency.
  • Macro Assisted Simplification: Simplifies the parameter parsing process further through macro definitions.
    • ArgsParse
    • syn_args::derive::declare
    • syn_args::derive::proc_attribute

Installation

Add the dependencies to your project:

cargo add syn
cargo add syn-args

Features

  • syn-args = { features = ["loose_mode"] }
    • Loose matching mode for parameters, where def::Bool and def::Array can be used without def::Options if they are optional parameters.

Usage

String Parsing (Basic Usage)

Below are some basic examples of string parsing:

For more examples, see the GitHub sample file

use syn::Error;
use syn_args::{def, derive::ArgsParse, ArgsParse, Formal};

#[derive(Debug, PartialEq, ArgsParse)]
pub enum ModuleArgs {
    F1(def::Int, def::Int),
    F2(def::Int),
    F3(def::Expr),
    F4(def::Array<def::Expr>),
    F5(ModuleSubObj),
    F6(def::Array<ModuleSubObj>),
}

#[derive(Debug, PartialEq, ArgsParse)]
pub struct ModuleSubObj {
    pub imports: def::Array<def::Expr>,
}

// Sample test function
fn test_formal_f3() {
    let res = ModuleArgs::parse("F(Hello)").unwrap();
    println!("{:?}", res);

    assert_eq!(res, ModuleArgs::F3(def::Expr("Hello".to_string())));
}

// More test functions...
fn main() {
    test_formal_f3();
}

TokenStream Parsing (Basic Usage)

TokenStream parsing examples show how to use syn_args to parse TokenStreams with complex nested structures:

View the full example: GitHub Link

Type definition:

#[derive(Debug, Clone, ArgsParse)]
pub struct ModuleOptions {
    pub imports: def::Array<def::Expr>,
    pub controllers: def::Array<def::Expr>,
    pub services: def::Array<def::Expr>,
    pub exports: def::Array<def::Expr>,
    pub interceptors: def::Array<def::Expr>,
}

Usage example:

let module_args = attr.meta.to_token_stream();
let module_options = syn::parse2::<syn_args::SynArgs>(module_args).unwrap().arguments::<syn_args::Arguments>().unwrap();
let module_options: ModuleOptions = module_options.try_into().unwrap();

Macro usage greatly simplifies the parameter parsing process and is the recommended advanced usage:

View the full example: GitHub Link

Usage example:

#[default_uses(LogInterceptor, LogInterceptorB, LogInterceptorC)]
pub struct AppModule;

Macro definition:

#[syn_args::derive::declare(def::Expr, def::Extends<def::Expr>)]
#[syn_args::derive::proc_attribute]
pub fn default_uses(args: Args, input: TokenStream) -> TokenStream {
    let args: Vec<def::Expr> = match args {
        Args::F1(first, other) => {
            // first => LogInterceptor
            // other => [LogInterceptorB, LogInterceptorC]
            let mut args = vec![first];
            args.append(&mut other.clone());
            args
        }
        _ => panic!("Invalid argument"),
    };
    let inter_names = args.iter().map(|arg| arg.to_path_name().unwrap()).collect::<Vec<String>>();

    DEFAULT_INTERS.lock().unwrap().append(&mut inter_names.clone());

    return input;
}

Note: This method is only applicable in the macro library development environment with [lib] proc-macro = true configuration.

Basic Types

  • def::Array: Array type.
  • def::Bool: Boolean type.
  • def::Float: Float type.
  • def::Int: Integer type.
  • def::Null: Null type.
  • def::Object: Object type.
  • def::String: String type.
  • def::Expr: Expression type, supports path and call parsing, etc.
  • def::Options: Optional parameter type.
  • def::Extends: Supports one or more parameters, and must be the last parameter of the function.

For specific type definitions, refer to the Type Definition Documentation.

About

License: MIT

View the Changelog

Dependencies