2个版本
| 0.1.1 | 2023年4月24日 | 
|---|---|
| 0.1.0 | 2023年4月23日 | 
#800 in 过程宏
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 ...
- 
参数 copy、clone、im_ref和mut_ref最多只能在一个属性中出现一次。
- 
参数 copy和clone可以在同一属性中使用。
- 
参数 im_ref和mut_ref还需要一个Rust类型,这是获取器的返回类型。
- 
参数 im_ref只是调用该类型的AsRef实现类似地,mut_ref调用AsMut实现。
- 
如果参数是 copy或clone,获取器名称将简单地是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