4 个版本

0.2.0 2021 年 6 月 6 日
0.1.4 2020 年 10 月 11 日
0.1.2 2020 年 8 月 12 日
0.1.1 2020 年 8 月 12 日
0.1.0 2020 年 8 月 12 日

#436 in 命令行界面

Download history 62/week @ 2024-03-13 107/week @ 2024-03-20 127/week @ 2024-03-27 193/week @ 2024-04-03 101/week @ 2024-04-10 108/week @ 2024-04-17 103/week @ 2024-04-24 112/week @ 2024-05-01 115/week @ 2024-05-08 93/week @ 2024-05-15 88/week @ 2024-05-22 121/week @ 2024-05-29 88/week @ 2024-06-05 64/week @ 2024-06-12 92/week @ 2024-06-19 60/week @ 2024-06-26

每月 349 次下载

MIT 许可证

11KB

Workflow Status

argio

将函数输入和输出转换为 stdio 的宏

此宏将函数的参数和返回值改为从标准输入和输出读取。

#[argio]
fn main(n: i32) -> i32 {
    n * 2
}

此函数不是直接接受一个整数作为参数,而是从标准输入读取一个整数,并将结果输出到标准输出。

由于此宏使用 proconio 作为输入的后端,因此您可以在函数中放入与可以传递给 input! 宏相同的参数(即使它们不是 Rust 的正确语法)。

#[argio]
fn main(n: usize, x: [i64; n]) -> i64 {
    x.into_iter().sum()
}

此函数读取以下输入

N
x_1 x_2 ... x_N

从标准输入,并将和输出到标准输出。

您可以通过设置 input 参数来更改输入的宏。宏将直接使用函数的参数。


macro_rules! my_input {
    ...
}

#[argio(input = my_input)]
fn main(n: usize, x: [i64; n]) -> i64 {
    x.into_iter().sum()
}

由于使用了 Display 特性来显示返回值,因此没有实现 Display 特性的函数,如 Vec,不能直接编译。

您可以通过使用实现 Display 特性的包装结构来自定义输出的行为。

struct Wrap<T>(T);

impl<T: Display> Display for Wrap<Vec<T>> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for (ix, r) in self.0.iter().enumerate() {
            if ix > 0 {
                write!(f, " ")?;
            }
            r.fmt(f)?;
        }
        Ok(())
    }
}

#[argio]
fn main(n: usize) -> Wrap<Vec<usize>> {
    Wrap((0..n).map(|i| i * 2).collect())
}
$ echo 10 | cargo run
0 2 4 6 8 10 12 14 16 18

当然,您也可以手动输出。如果函数的返回值是 (),则不会向标准输出输出任何内容,因此您可以手动输出并返回 ()

#[argio]
fn main(n: usize) {
    let ans = (0..n).map(|i| i * 2).collect::<Vec<_>>();
    for (i, x) in ans.into_iter().enumerate() {
        if i > 0 {
            print!(" ");
        }
        print!("{}", x);
    }
    println!();
}

您还可以通过宏参数指定输出的包装器。这有助于从代码中移除有关包装器的信息,从而使您可以将输出自定义移动到代码的模板部分。

#[argio(output = Wrap)]
fn main(n: usize) -> Vec<usize> {
    (0..n).map(|i| i * 2).collect()
}

如果指定了属性 multicase,则可以用于自动执行多个案例,这些案例以案例数量开始。

multicase 属性的值是要在每个案例顶部显示的字符串。变量 i 包含 0 原始的案例编号,因此您可以使用它来自定义显示。

#[argio(multicase = "Case #{i+1}: ", output = Wrap)]
fn main(n: usize) -> Vec<usize> {
    (0..n).map(|i| i * 2).collect()
}
$ echo "3 2 3 5" | cargo run
Case #1: 0 2
Case #2: 0 2 4
Case #3: 0 2 4 6 8

许可证:MIT

依赖项

~3.5–4.5MB
~89K SLoC