14个不稳定版本 (5个重大变更)

0.5.0 2024年8月7日
0.4.0 2024年5月12日
0.3.0 2023年5月25日
0.2.0 2020年8月18日
0.0.2 2017年4月23日

#30 in 过程宏

Download history 44203/week @ 2024-05-03 47252/week @ 2024-05-10 58032/week @ 2024-05-17 55383/week @ 2024-05-24 60196/week @ 2024-05-31 62995/week @ 2024-06-07 60334/week @ 2024-06-14 62648/week @ 2024-06-21 51618/week @ 2024-06-28 42117/week @ 2024-07-05 43348/week @ 2024-07-12 45536/week @ 2024-07-19 47368/week @ 2024-07-26 54783/week @ 2024-08-02 55408/week @ 2024-08-09 42108/week @ 2024-08-16

每月208,669次下载
用于 134 个crate(67 直接)

MIT许可证

37KB
573

Derive Getters

为命名结构体生成字段获取方法的简单 derive 宏。还包括一个额外的 derive,Dissolve,它消费结构体并返回所有字段的一个元组,顺序与声明顺序相同。对于目标结构体字段的任何文档注释都将复制到相应的获取器中。如果没有注释,则应生成注释。

当我在创建用于将JSON反序列化的各种数据结构时,产生了对 Getters 宏的需求。这些数据结构有很多字段需要访问,一旦创建后就不会改变。可以在任何地方使用 pub,但这将允许修改字段,这正是这个 derive 试图避免的。

获取器将根据 约定 生成。这意味着生成的方法将位于结构体命名空间内。

关于 Dissolve,有时在转换过程中必须消耗结构体。一个简单的方法是返回所有结构体字段的一个元组。因此,可以将 Dissolve 视为一个“获取(移动)所有内容”的方法调用。

本crate不会做什么

没有可变获取器,也没有计划。也没有设置器,将来也不会有。

Rust 文档

文档在此。

安装

添加到您的 Cargo.toml

[dependencies]
derive-getters = "0.5.0"

然后在需要的地方导入 GettersDissolve 宏(假设 2018 版本)。

use derive_getters::{Getters, Dissolve};

否则,只需在 crate 根目录导入。

#[macro_use]
extern crate derive_getters;

特性

  • auto_copy_getters - 启用自动为原始类型生成复制获取器(按值返回而不是按引用返回)。

用法

当您有一个需要自动 derive 获取器的结构体时...只需在顶部添加 derive,如下所示;

#[derive(Getters)]
pub struct MyCheesyStruct {
    x: i64,
    y: i64,
}

将为 MyCheesyStruct 生成一个新的实现。

/// Auto-generated by `derive_getters::Getters`.
impl MyCheesyStruct {
    /// Get field `x` from instance of `MyCheesyStruct`.
    pub fn x(&self) -> &i64 {
        &self.x
    }

    /// Get field `y` from instance of `MyCheesyStruct`.
    pub fn y(&self) -> &i64 {
        &self.y
    }
}

您还可以推导出“值获取器”,它们通过值而不是引用返回。

#[derive(Getters)]
pub struct MyCheesyStruct {
    #[getter(copy)]
    x: i64,
    #[getter(copy)]
    y: i64,
}

这将为 MyCheesyStruct 生成以下实现。

/// Auto-generated by `derive_getters::Getters`.
impl MyCheesyStruct {
    /// Get field `x` from instance of `MyCheesyStruct`.
    pub fn x(&self) -> i64 {
        self.x
    }

    /// Get field `y` from instance of `MyCheesyStruct`.
    pub fn y(&self) -> i64 {
        self.y
    }
}

如果您想自动为原始类型生成值获取器,可以启用 auto_copy_getters 功能。

建议启用 auto_copy_getters,因为它可以使您的代码更快(无需解引用指针)。Rust 参考文档 建议实现 Copy 特性

此软件包还可以处理具有简单泛型参数和生存期注解的结构体。有关更多信息,请参阅 文档

#[derive(Getters)]
pub struct StructWithGeneric<'a, T> {
    concrete: f64,
    generic: T,
    text: &'a str,
}

使用 Dissolve,可以这样使用:

#[derive(Dissolve)]
pub struct Solid {
    a: u64,
    b: f64,
    c: i64,
}

将为 Solid 生成以下实现:

/// Auto-generated by `derive_getters::Dissolve`.
impl Solid {
    /// Dissolve `Solid` into a tuple consisting of its fields in order of declaration.
    pub fn dissolve(self) -> (u64, f64, i64) {
      (self.a, self.b, self.c)
    }
}

属性

Getters 属性

  • 在字段上使用 #[getter(skip)] 以跳过为其生成获取器。
  • 在字段上使用 #[getter(copy)] 以通过复制而不是引用返回值(注意:值必须实现 Copy 特性)。
  • 在字段上使用 #[getter(rename = "name")] 以将获取器名称更改为 "name"。

Dissolve 属性

  • 在结构体上使用 #[dissolve(rename = "name")] 以将解溶函数的名称更改为 "name"。

注释保留

字段上的文档注释应复制到各自的获取器中。如果没有字段的注释,则应生成一个。

例如,这个结构体:

#[derive(Getters, Dissolve)]
#[dissolve(rename = "melt")]
struct Funky<'a, T> {
    number: i64,

    /// This is commented.
    commented: T,

    /// This comment is over
    /// many lines.
    /// Here's another line.
    #[getter(rename = "floating")]
    many_line: f32,

    /**
     * This is one of those
     * pesky multi-line
     * comments.
     */
    multi_line: &'a str,

    /// We don't care for this field.
    #[getter(skip)]
    ignore_me: u16,

    #[doc = r" A doc comment"]
    one_comment: u64,

    #[doc = include_str!("../COMMENTS.md")]
    incl_comment: u64,

    #[doc(hidden)]
    /// This comment should be hidden.
    hideme: u64,

    // This comment won't show up.
    bad: u64,
}

将自动生成以下内容:

/// Auto-generated by `derive_getters::Getters`.
impl<'a, T> Funky<'a, T> {
    /// Get field `number` from instance of `Funky`.
    pub fn number(&self) -> &i64 {
        &self.number
    }
    /// This is commented.
    pub fn commented(&self) -> &T {
        &self.commented
    }
    /// This comment is over
    /// many lines.
    /// Here's another line.
    pub fn floating(&self) -> &f32 {
        &self.many_line
    }
    /**
     * This is one of those
     * pesky multi-line
     * comments.
     */
    pub fn multi_line(&'a self) -> &'a str {
        self.multi_line
    }
    /// A doc comment
    pub fn one_comment(&self) -> &u64 {
        &self.one_comment
    }
    /**Comments sourced from a file included at compile time.
*/
    pub fn incl_comment(&self) -> &u64 {
        &self.incl_comment
    }
    #[doc(hidden)]
    /// This comment should be hidden.
    pub fn hideme(&self) -> &u64 {
        &self.hideme
    }
    /// Get field `bad` from instance of `Funky`.
    pub fn bad(&self) -> &u64 {
        &self.bad
    }
}
/// Auto-generated by `derive_getters::Dissolve`.
impl<'a, T> Funky<'a, T> {
    /// Dissolve `Funky` into a tuple consisting of its fields in order of declaration.
    pub fn melt(self) -> (i64, T, f32, &'a str, u16, u64, u64, u64, u64) {
        (
            self.number,
            self.commented,
            self.many_line,
            self.multi_line,
            self.ignore_me,
            self.one_comment,
            self.incl_comment,
            self.hideme,
            self.bad,
        )
    }
}

看!现在有了注释!

测试

由于新 #[cfg] 功能 auto_copy_getters 的存在,并非所有测试都将使用常规的 cargo test 运行。要一次性运行所有测试,请尝试使用 cargo-hack 软件包。安装后,运行:

cargo hack test --feature-powerset

注意事项

  1. 无法为单元结构体、元组结构体或枚举推导 Getters
  2. 无法为单元结构体或枚举推导 Dissolve
  3. 在没有 auto_copy_getters 的情况下,所有获取器方法都返回对其字段的不可变引用,&。这意味着对于某些类型,可能会变得有些尴尬。但是,在设置 auto_copy_getters 功能的情况下,生成的获取器将不会使用任何引用,用于原始的 Copy 类型。

备选方案

getset.

依赖项

~275–730KB
~17K SLoC