2个版本

0.1.1 2021年5月13日
0.1.0 2021年5月13日

#1570 in 过程宏

MIT/Apache

12KB
91 代码行

可变参数

vararg tests status Docs.rs link Crates.io link

此crate提供了一个 vararg 过程宏,可以应用于任何最后一个参数为 Vec、数组或切片引用的函数,将其转换为类似 println!format! 的可变参数宏

示例

use vararg::vararg;

#[vararg]
fn vararg_func<const L: usize>(a: &str, arr: [&str; L]) -> String {
    format!("\nfirst: {} \nlast: {} \n", a, arr.join(","))
}

fn main() {
    let s1 = "\n\
        first: first \n\
        last:  \n\
    ";
    let s2 = "\n\
        first: first \n\
        last: last \n\
    ";
    let s3 = "\n\
        first: first \n\
        last: last1,last2 \n\
    ";
    assert_eq!(s1, vararg_func!("first"));
    assert_eq!(s2, vararg_func!("first", "last"));
    assert_eq!(s3, vararg_func!("first", "last1", "last2"));
}

您可以在没有第一个必需参数的情况下创建可变参数函数(与C语言或nightly Rust中的可变参数函数不同)。例如,让我们创建一个不使用分隔符连接String切片的可变参数函数

use vararg::vararg;

#[vararg]
fn join_strs<const L: usize>(arr: [&str; L]) -> String {
    arr.join("")
}

fn main() {
    let s1 = "";
    let s2 = "ha";
    let s3 = "hahaha";
    assert_eq!(s1, join_strs!());
    assert_eq!(s2, join_strs!("ha"));
    assert_eq!(s3, join_strs!("ha", "ha", "ha"));
}

您还可以更改生成的宏的名称或最后一个参数的类型

use vararg::vararg;
use std::process::Command;

#[vararg(name = exec, type = slice)] // or type = array (default), or type = vec
fn exec_process(basename: &str, args: &[&str]) -> String {
    String::from_utf8(
        Command::new(basename)
            .args(args)
            .output()
            .expect("failed to execute echo")
            .stdout,
    )
    .expect("failed to parse hello")
}

fn main() {
    let (name, c) = if cfg!(target_os = "windows") {
        ("cmd", "/C")
    } else {
        ("sh", "-c")
    };
    assert_eq!("hello\n", exec!(name, c, "echo hello"));
}

许可协议

根据您选择,在Apache License 2.0或MIT许可协议下获得许可。

依赖项

~1.5MB
~34K SLoC