3 个版本 (重大更新)
0.3.0 | 2020年5月17日 |
---|---|
0.2.0 | 2020年5月16日 |
0.1.0 | 2020年5月10日 |
#36 in #ddd
用于 eventmill
20KB
253 行
eventmill-derive
为方便使用 eventmill
crate 提供derive宏
您可以通过两种方式引入宏。推荐的方式是使用主crate的 derive
功能
[dependencies]
eventmill = { version = "0.3", features = ["derive"] }
或替代方式
[dependencies]
eventmill = "0.3"
eventmill_derive = "0.3"
以下示例假设您使用 eventmill
crate 的 derive
功能推荐方式引入宏。
#[derive(EventType)]
#[derive(EventType)]
宏为您的事件实现 EventType
特质。事件可以是 struct
或 enum
。我们可以通过使用可选属性 event_type
、event_type_version
和 event_source
来配置生成的实现。
以下是一些示例
使用 struct
实现事件并指定所有可用属性。
use eventmill::EventType;
#[derive(EventType, Debug)]
#[event_type_version("V2")]
#[event_source("https://github.com/innoave/eventmill/examples/turtle")]
#[event_type("turtle-turned")]
pub struct TurtleTurned {
angle: f32,
}
fn main() {
let turtle = TurtleTurned { angle: 0.42 };
assert_eq!(turtle.event_type_version(), "V2");
assert_eq!(
turtle.event_source(),
"https://github.com/innoave/eventmill/examples/turtle"
);
assert_eq!(turtle.event_type(), "turtle-turned");
}
使用 enum
实现事件并指定所有可用属性。
use eventmill::EventType;
#[derive(EventType, Debug)]
#[event_type_version("V2")]
#[event_source("https://github.com/innoave/eventmill/examples/turtle")]
pub enum Turtle {
#[event_type("turtle-turned")]
Turned(f32),
#[event_type("turtle-moved")]
Moved { x: i32, y: i32 },
#[event_type("turtle-stopped")]
Stopped,
}
fn main() {
let turtle = Turtle::Stopped;
assert_eq!(turtle.event_type_version(), "V2");
assert_eq!(
turtle.event_source(),
"https://github.com/innoave/eventmill/examples/turtle"
);
assert_eq!(turtle.event_type(), "turtle-stopped");
let turtle = Turtle::Turned(0.42);
assert_eq!(turtle.event_type(), "turtle-turned");
let turtle = Turtle::Moved { x: 4, y: 2 };
assert_eq!(turtle.event_type(), "turtle-moved");
}
如果我们省略了任何或所有属性,宏将使用默认值。注意 event_type()
函数返回的默认名称。
use eventmill::EventType;
#[derive(EventType, Debug)]
pub enum Turtle {
Turned(f32),
Moved { x: i32, y: i32 },
Stopped,
}
fn main() {
let turtle = Turtle::Turned(0.42);
assert_eq!(turtle.event_type(), "Turtle::Turned");
let turtle = Turtle::Moved { x: 4, y: 2 };
assert_eq!(turtle.event_type(), "Turtle::Moved");
let turtle = Turtle::Stopped;
assert_eq!(turtle.event_type(), "Turtle::Stopped");
}
我们可以使用任何评估为 &str
的表达式作为属性的值。例如,使用 const
定义 event_source
属性。
use eventmill::EventType;
const EVENT_NAMESPACE: &str = "https://github.com/innoave/eventmill/examples/turtle";
#[derive(EventType, Debug)]
#[event_source(EVENT_NAMESPACE)]
pub struct TurtleTurned {
angle: f32,
}
fn main() {
let turtle = TurtleTurned { angle: 0.42 };
assert_eq!(turtle.event_type_version(), "V0");
assert_eq!(turtle.event_source(), EVENT_NAMESPACE);
assert_eq!(turtle.event_type(), "TurtleTurned");
}
#[derive(AggregateType)]
宏 #[derive(AggregateType)]
实现了为您的聚合类型提供 AggregateType
特性。目前,此宏只能用于 struct
类型。我们可以使用两个可选属性 #[id_field]
和 #[initialize_with_defaults]
来配置宏。
当指定了 #[id_field]
属性时,宏将额外实现 WithAggregateId
特性。此属性有一个参数,即结构体中 id 字段的标识符。
#[initialize_with_defaults]
属性告诉宏使用结构体中每个字段的默认值来实现 InitializeAggregate
特性。这假设结构体字段中使用的类型实现了 Default
特性。#[initialize_with_defaults]
属性要求结构体也指定了 #[id_field]
属性。
以下是一些示例
使用带有所有可选属性的 AggregateType
宏为特性 AggregateType
、WithAggregateId
和 InitializeAggregate
实现派生
use eventmill::{AggregateType, InitializeAggregate, WithAggregateId};
#[derive(AggregateType, Debug, PartialEq)]
#[id_field(id)]
#[initialize_with_defaults]
pub struct Turtle {
id: String,
x: f32,
y: f32,
direction: f32,
speed: f32,
pen: bool,
}
#[test]
fn main() {
let expected_turtle = Turtle {
id: "4711".to_string(),
x: Default::default(),
y: Default::default(),
direction: Default::default(),
speed: Default::default(),
pen: Default::default(),
};
let new_turtle = Turtle::initialize("4711".to_string());
assert_eq!(new_turtle, expected_turtle);
assert_eq!(new_turtle.aggregate_id(), "4711");
assert_eq!(Turtle::aggregate_type(), "Turtle");
}
仅派生 AggregateType
的实现。不要指定任何其他属性
use eventmill::AggregateType;
#[derive(AggregateType, Debug)]
pub struct Turtle {
id: String,
x: f32,
y: f32,
direction: f32,
speed: f32,
pen: bool,
}
#[test]
fn main() {
assert_eq!(Turtle::aggregate_type(), "Turtle");
}
派生特性 AggregateType
和 WithAggregateId
的实现
use eventmill::{AggregateType, WithAggregateId};
#[derive(AggregateType, Debug)]
#[id_field(id)]
pub struct Turtle {
id: String,
x: f32,
y: f32,
direction: f32,
speed: f32,
pen: bool,
}
#[test]
fn main() {
let turtle = Turtle {
id: "0815".to_string(),
x: -0.5,
y: 0.3,
direction: 0.42,
speed: 1.0,
pen: true,
};
assert_eq!(turtle.aggregate_id(), "0815");
assert_eq!(Turtle::aggregate_type(), "Turtle");
}
依赖项
~1.5MB
~35K SLoC