2个版本

0.1.1 2023年4月24日
0.1.0 2023年4月23日

#800 in 过程宏

MIT许可证

15KB
232

你的标记...准备...Rust!

可能会出错,错误处理是原始的。请自行承担风险

此库提供单个宏 GetSet,允许您为您的结构体编写基本的获取器和设置器。

我写这个是因为我厌倦了手动编写它们。在大多数情况下,您可能不需要这种原始的获取器和设置器,但我需要它们(以及“muh过程宏” ¯\_()_/¯)。

如果您发现了一个错误或有一个看起来很适合的功能,请随时贡献。


基本用法

您可以使用宏如下

#[derive(GetSet)]
struct Foo {
    #[get(clone)]
    bar: String, 
    #[get(copy)]
    pub baz: f32,
    #[get(im_ref(&Path), mut_ref(&mut Path))]
    qux: PathBuf
    #[set]
    pub quux: Option<u64>, 
}

这些应该有效转换为

impl Foo {
    pub fn get_bar(&self) -> String {
        self.bar.clone()
    }
    pub fn get_baz(&self) -> String {
        self.baz.clone()
    }
    pub fn get_qux_ref(&self) -> &Path {
        self.qux.as_ref()
    }
    pub fn get_qux_ref_mut(&self) -> &mut Path {
        self.qux.as_mut()
    }
    pub fn set_quux(&mut self, value: Option<u64>) {
        self.quux = value
    }
}

备注

  • 每个字段最多只能有一个 #[get)] 属性和最多一个 #[set] 属性。

    所以,这是可以的

    ...
    #[get(clone, im_ref(&i32), mut_ref(&mut i32))]
    corge: i32
    ...
    

    这是不可以的

    ...
    #[get(clone)]
    #[get(im_ref(&i32))]
    #[get(mut_ref(&mut i32))]
    corge: i32
    ...
    
  • 参数 copycloneim_refmut_ref 最多只能在一个属性中出现一次。

  • 参数 copyclone 可以在同一属性中使用。

  • 参数 im_refmut_ref 还需要一个Rust类型,这是获取器的返回类型。

  • 参数 im_ref 只是调用该类型的 AsRef 实现类似地,mut_ref 调用 AsMut 实现。

  • 如果参数是 copyclone,获取器名称将简单地是 get_<字段名>,其中 <字段名> 被替换为属性所在字段的名称。(参见上面的示例

  • 同样,如果参数是 im_ref,获取器名称将是 get_<字段名>_ref,而对于 mut_ref 的情况,则是 get_<字段名>_ref_mut

  • 属性 #[set] 不接受任何参数,生成的设置器名称是 set_<字段名>

  • 所有生成的函数都具有 pub 可见性。


有趣

也存在一个特殊的获取器参数 - funky,允许你进行有趣的操作(duh)。这允许你使用任何 Rust 表达式来操作获取到的值。

...
#[get(funky(grault_opt :: grault.ok() => Option<i32>))]
grault: Result<i32>
#[get(funky(garply_mut_opt :: mut garply.as_mut() => Option<&mut i32>))]
garply: Option<f32>
...

这实际上相当于

...
pub fn get_grault_opt(&self) -> Option<i32> {
    self.grault.ok()
}
pub fn get_garply_mut_opt(&mut self) -> Option<&mut i32> {
    self.garply.as_mut()
}
...

在使用它时必须小心,因为技术上你可以做类似的事情

...
#[get(funky(waldo_funk :: mut { 
    let foo = *waldo; 
    let bar = (foo * 420) as f32;
    *waldo = (bar - 1.69) as i32;
    bar 
} => f32))]
pub waldo: i32
...

这会翻译成类似的东西

... 
pub fn get_waldo_funk(&mut self) -> f32 {
    let foo = *self.waldo;
    let bar = (foo * 420) as f32;
    self.waldo = (bar - 1.69) as i32;
    bar
}
... 

备注

  • 这是唯一可能出现多次的参数。
  • funky 接收
    • 用于创建获取器名称的标识符
    • 然后,:: 符号
    • 然后,一个可选的 mut 关键字,指定接收器是 &mut self 还是 &self
    • 然后,=> 符号
    • 然后,获取器的返回类型
  • 我只添加了这个,因为我发现自己经常需要调用字段的单个方法并返回该值的获取器(参见示例
  • 如果你需要在字段值上执行超过 一行 的处理,则可能不会使用它(或者如果你像我一样懒惰,也可以使用它 :D)

依赖关系

~1.5MB
~36K SLoC