#getter-setter #getters #setters #getter #setter #macro #proc-macro

getset-scoped

Getset,我们准备好了!一个用于生成字段最基本获取器和设置器的过程宏。

1个不稳定版本

0.1.2 2022年8月21日

#1921 in 过程宏

Download history 237/week @ 2024-04-08 162/week @ 2024-04-15 117/week @ 2024-04-22 87/week @ 2024-04-29 215/week @ 2024-05-06 270/week @ 2024-05-13 168/week @ 2024-05-20 337/week @ 2024-05-27 370/week @ 2024-06-03 501/week @ 2024-06-10 415/week @ 2024-06-17 348/week @ 2024-06-24 148/week @ 2024-07-01 9/week @ 2024-07-22

173 每月下载量
2 crate中使用

MIT 许可证

22KB
296

getset

Download License Docs Coverage Status

Getset,我们准备好了!

这是一个用于生成字段最基本获取器和设置器的过程宏。

获取器作为 fn field(&self) -> &type 生成,而设置器作为 fn field(&mut self, val: type) 生成。

这些宏不适用于需要在设置器和获取器内部进行自定义逻辑的字段。在这种情况下,请自己编写!

use getset_scoped::{CopyGetters, Getters, MutGetters, Setters};

#[derive(Getters, Setters, MutGetters, CopyGetters, Default)]
pub struct Foo<T>
where
    T: Copy + Clone + Default,
{
    /// Doc comments are supported!
    /// Multiline, even.
    #[getset(get, set, get_mut)]
    private: T,

    /// Doc comments are supported!
    /// Multiline, even.
    #[getset(get_copy = "pub", set = "pub", get_mut = "pub")]
    public: T,
}

fn main() {
    let mut foo = Foo::default();
    foo.set_private(1);
    (*foo.private_mut()) += 1;
    assert_eq!(*foo.private(), 2);
}

您可以使用 cargo-expand 生成输出。以下是上述宏生成的函数(使用 cargo expand --example simple 进行复制)

use getset_scoped::{Getters, MutGetters, CopyGetters, Setters};
pub struct Foo<T>
where
    T: Copy + Clone + Default,
{
    /// Doc comments are supported!
    /// Multiline, even.
    #[getset(get, get, get_mut)]
    private: T,
    /// Doc comments are supported!
    /// Multiline, even.
    #[getset(get_copy = "pub", set = "pub", get_mut = "pub")]
    public: T,
}
impl<T> Foo<T>
where
    T: Copy + Clone + Default,
{
    /// Doc comments are supported!
    /// Multiline, even.
    #[inline(always)]
    fn private(&self) -> &T {
        &self.private
    }
}
impl<T> Foo<T>
where
    T: Copy + Clone + Default,
{
    /// Doc comments are supported!
    /// Multiline, even.
    #[inline(always)]
    pub fn set_public(&mut self, val: T) -> &mut Self {
        self.public = val;
        self
    }
}
impl<T> Foo<T>
where
    T: Copy + Clone + Default,
{
    /// Doc comments are supported!
    /// Multiline, even.
    #[inline(always)]
    fn private_mut(&mut self) -> &mut T {
        &mut self.private
    }
    /// Doc comments are supported!
    /// Multiline, even.
    #[inline(always)]
    pub fn public_mut(&mut self) -> &mut T {
        &mut self.public
    }
}
impl<T> Foo<T>
where
    T: Copy + Clone + Default,
{
    /// Doc comments are supported!
    /// Multiline, even.
    #[inline(always)]
    pub fn public(&self) -> T {
        self.public
    }
}

可以在结构体级别为结构体中的所有字段设置属性。字段级别的属性优先。

#[macro_use]
extern crate getset_scoped;

mod submodule {
    #[derive(Getters, CopyGetters, Default)]
    #[get_copy = "pub"] // By default add a pub getting for all fields.
    pub struct Foo {
        public: i32,
        #[get_copy] // Override as private
        private: i32,
    }
    fn demo() {
        let mut foo = Foo::default();
        foo.private();
    }
}
fn main() {
    let mut foo = submodule::Foo::default();
    foo.public();
}

出于某些目的,在获取器上使用 get_ 前缀对于兼容性或旧版本原因是有用的。这可以通过 with_prefix 实现。

#[macro_use]
extern crate getset_scoped;

#[derive(Getters, Default)]
pub struct Foo {
    #[get = "pub with_prefix"]
    field: bool,
}

fn main() {
    let mut foo = Foo::default();
    let val = foo.get_field();
}

当使用结构体级别的属性时,可以通过 #[getset(skip)] 跳过字段的设置器和获取器生成。

use getset_scoped::{CopyGetters, Setters};

#[derive(CopyGetters, Setters)]
#[getset(get_copy, set)]
pub struct Foo {
    // If the field was not skipped, the compiler would complain about moving
    // a non-copyable type in copy getter.
    #[getset(skip)]
    skipped: String,

    field1: usize,
    field2: usize,
}

impl Foo {
    // It is possible to write getters and setters manually,
    // possibly with a custom logic.
    fn skipped(&self) -> &str {
        &self.skipped
    }

    fn set_skipped(&mut self, val: &str) -> &mut Self {
        self.skipped = val.to_string();
        self
    }
}

依赖项

~1.5MB
~36K SLoC