#arguments #optional #function #const #macro

optargs

轻松为具有可选参数的函数创建宏

3 个版本

0.1.2 2021年4月25日
0.1.1 2021年4月19日
0.1.0 2021年3月31日

#2642 in Rust 模式

Download history 98/week @ 2024-04-04 59/week @ 2024-04-11 83/week @ 2024-04-18 144/week @ 2024-04-25 94/week @ 2024-05-02 84/week @ 2024-05-09 166/week @ 2024-05-16 104/week @ 2024-05-23 87/week @ 2024-05-30 69/week @ 2024-06-06 53/week @ 2024-06-13 68/week @ 2024-06-20 56/week @ 2024-06-27 37/week @ 2024-07-04 87/week @ 2024-07-11 95/week @ 2024-07-18

每月287次下载

MIT/Apache

7KB

OptArgs:Rust 函数的可选参数

为任何函数启用可选参数

#[optargs::optfn]
pub fn plot(
    x: Vec<i32>,
    y: Option<Vec<i32>>,
    title: Option<&str>,
    xlabel: Option<&str>,
    ylabel: Option<&str>,
    legend: Option<bool>
) {}

// can now call it with optional arguments
plot!(
    x: vec![1,2,3], 
    y: vec![1,2,3], 
    title: "Awesome plot", 
    xlabel: "x axis", 
    ylabel: "y axis"
);

...或结构体

#[derive(optargs::OptStruct)]
pub struct Scatter {
    x: Vec<i32>,
    y: Option<Vec<i32>>,
    title: Option<&str>,
    xlabel: Option<&str>,
    ylabel: Option<&str>,
    legend: Option<bool>
}
impl Scatter {
    fn plot(self) {/* custom impl that references self */}
}

// Call it
Scatter!{ x: vec![1,2,3], y: vec![1,2,3] }.plot()

此包特别适用于清理依赖构建器较多的代码库,并使库 API 更易用。它还很好地与 Rust-Analyzer 集成,不产生较长的编译时间。


此包添加了两个宏,使得向函数添加可选参数变得简单。

  • #[optargs] - 获取一个用于调用具有可选参数的函数的宏。
  • #[derive(OptStruct)] - 获取一个具有可选字段的结构的类型构建器。

此包利用了 Rust 稳定版 (1.51) 中最近的 const_generics,因此我们的 MSRV 是 1.51。

注意事项

  • 所有可选参数都将默认为无。我们目前不提供自定义默认值(如果有人想要,请接受 PR!)。
  • 所有可选参数必须位于必需参数之后。
  • 无名称的位置参数必须位于正确的位置。
  • 所有参数都可以是必需的,但现在您可以命名它们。
  • 传统 macro_rules 作用域适用,即您不能在函数声明之前使用宏。然而,它们通过 macro_export 导出,因此您可以在任何地方使用它们,例如 crate::$MACRO。目前,还没有办法禁用此功能,因此您不能有两个具有相同名称的函数。如果这成为问题,我们很高兴接受 PR。

工作原理

OptArgs 使用 const generics 来确保编译时正确性。我已经自由地扩展并使参考示例中的宏更加人性化。

本质上,我们将必需参数的状态编码到具有 const 参数的 ZST 中。当添加每个必需参数时,我们将 const 参数从 false 翻转到 true。只有在输入所有必需参数后,我们才能调用原始函数。

struct Validator<const A: bool> {}
impl Validator<true> { fn validate(self) {} }
impl<const A: bool> Validator<A> { fn b(self) -> Validator<A> { self }}
// Not to worry about the unsafe, Validator is a ZST and has no place in memory.
// All this validation code will be removed anyways.
impl Validator<false> { fn a(self) -> Validator<true> { unsafe {std::mem::transmute(self)} } }

许可证

以下任一许可证下许可

由您自行选择。

贡献

除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交以包含在作品中的任何贡献,将按上述方式双授权,没有任何附加条款或条件。

依赖

约1.5MB
约35K SLoC