#derive #macro-derive #traits #procedural #macro #proc-macro #struct-fields

无 std derive-ctor

添加 #[derive(ctor)] 属性,允许自动生成结构体、枚举和联合构造函数。

13 个版本 (7 个稳定版)

1.0.6 2024 年 6 月 11 日
1.0.5 2024 年 6 月 9 日
1.0.0 2024 年 5 月 31 日
0.2.3 2024 年 5 月 30 日
0.1.1 2024 年 5 月 28 日

Rust 模式 中排名 477

MIT 许可证

52KB
988

derive-ctor

derive-ctor 是一个 Rust 程序化宏 crate,允许您轻松生成结构体的构造方法。使用 #[derive(ctor)] 属性,您可以自动为结构体、枚举和联合创建构造函数。该 crate 还提供各种选项来自定义生成的构造函数方法。

功能

  • 使用 #[derive(ctor)] 自动生成结构体、枚举和联合的构造方法。
  • 使用 #[ctor(visibility method_name)] 自定义自动生成的构造方法的名称和可见性。
    • 支持使用 "const" 关键字添加常量构造函数。
    • 提供名称列表以生成多个构造函数。
  • 使用以下属性在构造函数中自定义字段行为(用于 #[ctor(PROPETY)])
    • cloned - 将参数类型更改为接受引用类型,然后将该引用类型克隆到创建的结构体中。
    • default - 从生成的方法中排除字段并使用其默认值。
    • expr(表达式) - 从生成的方法中排除字段并使用定义的表达式作为其默认值。
      • expr!(表达式) 以将注解字段作为必填参数添加,允许表达式引用自身。
      • 使用 expr(类型 -> 表达式) 添加具有指定类型的参数,该参数将用于生成最终字段的值。
    • into - 将生成方法的参数类型更改为 impl Into<Type>
    • iter(起始类型) - 将生成方法的参数类型更改为 impl IntoIterator<Item=FROM_TYPE>
  • 无需依赖标准库(开箱即用无-std)。
  • 与结构体、枚举和联合的可用性可切换为功能(默认全部启用)

基本用法

derive-ctor 添加到您的 Cargo.toml

[dependencies]
derive-ctor = "1.0.6"

使用 #[derive(ctor)] 注解您的结构体以自动生成一个 new 构造函数

use derive_ctor::ctor;

#[derive(ctor)]
struct MyStruct {
    field1: i32,
    field2: String
}

let my_struct = MyStruct::new(1, String::from("Foo"));

结构体配置

可见性和构造函数名称

您可以使用 #[ctor] 属性修改生成方法的名称和可见性,并在 ctor 派生后定义额外的构造函数。

在以下示例中,创建了三个构造函数方法: newwith_defaultsinternal。这些方法都继承了 #[ctor] 属性中定义的相应可见性。

use derive_ctor::ctor;

#[derive(ctor)]
#[ctor(pub new, pub(crate) other, const internal)]
struct MyStruct {
    field1: i32,
    field2: String
}

let my_struct1 = MyStruct::new(100, "A".to_string());
let my_struct2 = MyStruct::other(200, "B".to_string());
let my_struct3 = MyStruct::internal(300, "C".to_string());

自动实现 "Default" 特性

可以通过在构造函数属性中指定名为 default 的构造函数来自动实现 Default 特性。注意:为了使实现有效,所有字段都必须具有生成的值。此外,声明 default(all) 将自动将所有未注解字段标记为 #[ctor(default)]

use derive_ctor::ctor;

#[derive(ctor)]
#[ctor(default)]
struct MyStruct {
    #[ctor(default)]
    field1: i32,
    #[ctor(expr(true))]
    field2: bool
}

let default: MyStruct = Default::default();


#[derive(ctor)]
#[ctor(default(all))]
struct OtherStruct {
    field1: i32,
    #[ctor(expr(true))]
    field2: bool
}

let default2: OtherStruct = Default::default();

构造函数属性

自定义构造函数定义还可以采取以下属性以在所有未配置的字段上实施

  • default - 将所有未注解字段标记为 #[ctor(default)]
  • 进入 - 标记所有未注释字段为 #[ctor(into)]
use derive_ctor::ctor;

#[derive(ctor)]
#[ctor(new(into), with_defaults(default))]
struct MyStruct {
    name: String,
    #[ctor(expr(13))]
    value: i32
}

let example1 = MyStruct::new("FooBar");
let example2 = MyStruct::with_defaults();

枚举和联合配置

默认情况下,将为每个变体生成一个构造函数。此构造函数默认将与各自的变体名称匹配,并且是公开的。可以通过注释枚举为 #[ctor(prefix = PREFIX, visibility = VISIBILITY)] 来更改此默认行为。请注意,在属性中这两个参数都是可选的。指定此属性将更改每个变体的默认生成方法,但每个变体还可以定义自己的配置,该配置将覆盖枚举中定义的配置。

标准变体构造函数示例

use derive_ctor::ctor;

#[derive(ctor)]
enum MyEnum {
    Variant1,
    Variant2(i32),
    Variant3 { value: bool }
}

let v1 = MyEnum::variant1();
let v2 = MyEnum::variant2(100);
let v3 = MyEnum::variant3(true);

配置的变体构造函数示例

变体构造函数配置与结构体构造函数配置相同。请参考以下示例语法,或返回到结构体构造函数配置以获取更多信息。

use derive_ctor::ctor;

#[derive(ctor)]
#[ctor(prefix = new, vis = pub(crate))]
enum MyEnum {
    #[ctor(const pub v1, other)]
    Variant1,
    Variant2,
    Variant3
}

const v1_1: MyEnum = MyEnum::v1();
let v1_2 = MyEnum::other();
let v2 = MyEnum::new_variant2();
let v3 = MyEnum::new_variant3();

如果一个变体使用 #[ctor(none)] 进行继承,则不会为其生成构造函数。同样,如果一个变体使用 #[ctor(default)] 进行继承,则将自动实现 Default 特性以生成该变体。

联合表达与枚举相同的行为,但适用于联合的字段而不是枚举的变体。

use derive_ctor::ctor;

#[derive(ctor)]
#[ctor(prefix = new, vis = pub(crate))]
union MyUnion {
    #[ctor(const new)]
    v1: i32,
    v2: f32,
    v3: u32
}

const VAL: MyUnion = MyUnion::new(100);
let v2 = MyUnion::new_v2(123.231);
let v3 = MyUnion::new_v3(414224); 

字段配置

字段也可以使用 #[ctor(PROPERTY)] 进行注释以更改生成方法中的行为。**这些配置适用于所有枚举类型和结构体!**以下是可以与字段属性一起使用的可用属性:

#[ctor(cloned)] - 此属性创建一个接受注释字段类型引用的参数,然后克隆它以生成最终值。

use derive_ctor::ctor;

#[derive(ctor)]
struct MyStruct {
    field1: i32,
    #[ctor(cloned)]
    field2: String
}

let string = String::from("Foo");
let my_struct = MyStruct::new(100, &string);

#[ctor(default)] - 此属性将注释字段排除在构造函数之外,并使用其默认值。

use derive_ctor::ctor;

#[derive(ctor)]
struct MyStruct {
    field1: i32,
    #[ctor(default)]
    field2: String
}

let my_struct = MyStruct::new(100);

#[ctor(into)] - 此属性修改了生成的转换方法的注释字段的参数类型,将其从 Type -> impl Into<Type>

use derive_ctor::ctor;

#[derive(ctor)]
struct MyStruct {
    field1: i32,
    #[ctor(into)] // the parameter type will now be impl Into<String> instead of String
    field2: String
}

let my_struct = MyStruct::new(100, "Foo");

#[ctor(expr(EXPRESSION))] - 此属性将注释字段从构造函数中排除,并使用定义的表达式生成其值。

替代方案

  • #[ctor(expr!(EXPRESSION))] - 与上述属性不同,此属性将注释字段作为给定构造函数的必需参数添加,这允许提供的 EXPRESSION 引用该参数并修改传递的值。
  • #[ctor(expr(TYPE -> EXPRESSION))] - 此属性的行为类似于上面的变体,但是所需的参数类型将是属性中提供的类型,从而允许构造函数接受并映射一个类型到结构字段使用的类型。
use derive_ctor::ctor;

#[derive(ctor)]
struct MyStruct {
    field1: i32,
    #[ctor(expr(String::from("Foo")))]
    field2: String,
    #[ctor(expr!(field3 + 100))]
    field3: u32,
    #[ctor(expr(i32 -> field4 < 0))]
    field4: bool
}

let my_struct = MyStruct::new(100, 5, -20); // generates MyStruct { field1: 100, field2: "foo", field3: 105, field4: true }

#[ctor(iter(TYPE))] - 此属性添加了一个类型为 impl IntoIterator<Item=TYPE> 的参数,然后通过在参数值上调用 .into_iter().collect() 来生成注释的结构值。

use std::collections::HashSet;
use derive_ctor::ctor;

#[derive(ctor)]
struct MyStruct {
    field1: i32,
    #[ctor(iter(usize))]
    field2: HashSet<usize>
}

let my_struct = MyStruct::new(0, vec![1, 1, 2, 3, 4]);

高级配置

字段属性可以通过与使用生成的值的方法对应的索引列表进行额外配置。这允许创建具有不同参数要求的多功能函数。

use derive_ctor::ctor;

#[derive(ctor)]
#[ctor(new, with_defaults)]
struct MyStruct {
    field1: i32,
    #[ctor(default = [1])]
    field2: String,
    #[ctor(default = 1)] // brackets can be removed if specifying only 1 index
    field3: bool,
    #[ctor(default = [0, 1])]
    field4: u64,
    #[ctor(default)] // this is the same as specifying all indices
    field5: u64
}

let my_struct1 = MyStruct::new(100, "Foo".to_string(), true);
let my_struct2 = MyStruct::with_defaults(100);

非默认特性

缩写 - 允许在字段上使用“缩写”属性。例如,您可以使用 #[expr(EXPRESSION)] 代替 #[ctor(expr(EXPRESSION)]

use derive_ctor::ctor;

#[derive(ctor)]
struct MyStruct {
    #[expr(100)]
    value: u32
}

let my_struct = MyStruct::new();

依赖项

~280–740KB
~18K SLoC