4 个版本

0.2.1 2024 年 1 月 20 日
0.2.0 2023 年 11 月 4 日
0.1.1 2023 年 10 月 31 日
0.1.0 2023 年 9 月 17 日

#partial 中排名 #67

Download history 6/week @ 2024-03-13 1/week @ 2024-03-20 7/week @ 2024-03-27 21/week @ 2024-04-03 18/week @ 2024-04-10 25/week @ 2024-04-17 39/week @ 2024-04-24 36/week @ 2024-05-01 25/week @ 2024-05-08 42/week @ 2024-05-15 50/week @ 2024-05-22 33/week @ 2024-05-29 13/week @ 2024-06-05 50/week @ 2024-06-12 63/week @ 2024-06-19 18/week @ 2024-06-26

每月下载量 146
用于 部分

MIT/Apache 协议

51KB
961 行代码(不含注释)

部分

提供可配置的 推导宏,该宏生成另一个具有相同字段的结构体,但字段被包裹在 Option<T> 中,并实现 Partial 以允许有条件地将生成的结构体字段应用于基本结构体字段。

部分 提供了 Partial trait,允许将另一个结构体的值应用于 self,意图是另一个结构体反映 self 的字段,但被包裹在 Option<T> 中。

此外,部分推导(或启用 derive 功能的 部分)支持自动生成一个镜像结构体,每个字段都被包裹在 Option<T> 中,并生成一个 Partial 实现,允许将镜像结构体的 Some 字段应用于基本结构体。我预计大多数人会对使用推导宏感兴趣。

使用方法

使用 derive

// `partially` installed with feature `derive`
use partially::Partial;

// define a base structure, with the `Partial` derive macro
#[derive(Partial)]
// further, instruct the macro to derive `Default` on the generated structure
#[partially(derive(Default))]
struct Data {
    // since no field options are specified, this field will be mapped
    // to an `Option<String>` in the generated structure
    value: String,
}

// example usage
fn main() {
    // since we derived default for the generated struct, we can use that
    // to obtain a partial struct filled with `None`.
    let empty_partial = PartialData::default();

    // we can, of course, also specify values ourself
    let full_partial = PartialData {
        value: Some("modified".to_string()),
    };

    // define a "base" that we'll operate against
    let mut full = Data {
        value: "initial".to_string(),
    };

    // apply the empty partial (note that `false` is returned, indicating nothing was applied)
    assert!(!full.apply_some(empty_partial));

    // note that applying the empty partial had no effect
    assert_eq!(full.value, "initial".to_string());

    // apply the full partial (note that `true` is returned, indicating something was applied)
    assert!(full.apply_some(full_partial));

    // note that applying the full partial modified the value
    assert_eq!(full.value, "modified".to_string());
}

不使用 derive

use partially::Partial;

struct Base {
    value: String,
}

#[derive(Default)]
struct PartialBase {
    value: Option<String>,
}

impl Partial for Base {
    type Item = PartialBase;

    #[allow(clippy::useless_conversion)]
    fn apply_some(&mut self, partial: Self::Item) -> bool {
        let will_apply_some = partial.value.is_some();

        if let Some(value) = partial.value {
            self.value = value.into();
        }

        will_apply_some
    }
}

fn main() {
    let empty_partial = PartialBase::default();
    let full_partial = PartialBase {
        value: Some("modified".to_string()),
    };

    let mut data = Base {
        value: "initial".to_string(),
    };

    assert!(!data.apply_some(empty_partial));

    assert_eq!(data.value, "initial".to_string());

    assert!(data.apply_some(full_partial));

    assert_eq!(data.value, "modified".to_string())
}

结构体选项

derive

使用示例:#[部分(derive(Debug, Default))]

指示宏在生成的结构体上生成一个 #[derive(...)] 属性。

注意:当与 skip_attributes 选项一起使用时,仍然会将 derive 属性添加到生成的结构体中。

rename

使用示例: #[partially(rename = "MyGeneratedStruct")]

指示宏使用给定的标识符为生成的结构体。默认情况下,使用 PartialBaseStructName,其中 BaseStructName 是原始结构体的名称。

attribute

使用示例: #[partially(attribute(serde(rename_all = "PascalCase")))]

指示宏向生成的结构体添加额外的属性。默认情况下,将基础结构体上定义的属性转发到生成的结构体,除非存在 skip_attributes 选项。

skip_attributes

使用示例: #[partially(skip_attributes)]

指示宏跳过从原始结构体到生成结构体的属性转发。默认情况下,所有存在于基础结构体上的属性都将添加到生成的结构体中。

注意:当与 derive 选项一起使用时,derive 属性 仍然会被添加到生成的结构体中

注意:当与 attribute 选项一起使用时,指定的属性 仍然会被添加到生成的结构体中

crate

使用示例: #[partially(crate = "my_partially_crate")]

指示宏使用不同的基础路径进行 Partial 特性实现。默认情况下使用 partially。如果你已经分叉了 partially crate,这可能会很有用。

字段选项

rename

使用示例: #[partially(rename = "new_field_name")]

指示宏使用指定的标识符来为生成的字段命名。默认情况下,使用与基本结构相同的名称。

省略

使用示例: #[partially(omit)]

指示宏从生成的结构体中省略该字段。默认情况下,不省略任何字段。

透明

使用示例: #[partially(transparent)]

指示宏跳过将生成的字段包装在 Option<T> 中,而是透明地将字段类型映射到生成的结构体中。

as_type

使用示例: #[partially(as_type = "Option<f32>")]

指示宏在生成字段时使用提供的类型,而不是 Option<T>。请注意,提供的类型将直接使用,因此如果您期望一个 Option<T> 值,则需要手动指定。

注意:当使用 as_type 时,给定类型必须 Into<BaseType>,其中 BaseType 是原始字段类型。这是 Partial 特性实现所必需的。

依赖

~0.6–1.1MB
~25K SLoC