1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! Building entities in tests without a repository.
//!
//! Enabled by the `testing` feature. Add it to `[dev-dependencies]` only, so
//! it is part of `cargo test` builds and absent from production builds:
//!
//! ```toml
//! [dev-dependencies]
//! es-entity = { version = "*", features = ["testing"] }
//! ```
//!
//! Then `use es_entity::testing::*;` at the top of a `#[cfg(test)]` module:
//!
//! ```rust
//! use es_entity::{testing::*, *};
//! use serde::{Deserialize, Serialize};
//!
//! entity_id! { UserId }
//!
//! #[derive(EsEvent, Debug, Serialize, Deserialize)]
//! #[serde(tag = "type", rename_all = "snake_case")]
//! #[es_event(id = "UserId")]
//! pub enum UserEvent {
//! Initialized { id: UserId, name: String },
//! NameUpdated { name: String },
//! }
//!
//! #[derive(EsEntity)]
//! pub struct User {
//! pub id: UserId,
//! pub name: String,
//! events: EntityEvents<UserEvent>,
//! }
//!
//! impl TryFromEvents<UserEvent> for User {
//! fn try_from_events(events: EntityEvents<UserEvent>) -> Result<Self, EntityHydrationError> {
//! let mut name = String::new();
//! for event in events.iter_all() {
//! match event {
//! UserEvent::Initialized { name: n, .. } | UserEvent::NameUpdated { name: n } => {
//! name = n.clone()
//! }
//! }
//! }
//! Ok(User { id: events.id().clone(), name, events })
//! }
//! }
//!
//! pub struct NewUser {
//! name: String,
//! }
//!
//! impl IntoEvents<UserEvent> for NewUser {
//! type IdSource = FromRepo;
//!
//! fn into_events(self, builder: EntityEventsBuilder<UserEvent, FromRepo>) -> EntityEvents<UserEvent> {
//! let id = builder.id();
//! builder.initial_events([UserEvent::Initialized { id, name: self.name }])
//! }
//! }
//!
//! let id = UserId::new();
//! let user = User::hydrate_from_events(
//! id,
//! [
//! UserEvent::Initialized { id, name: "Alice".to_string() },
//! UserEvent::NameUpdated { name: "Bob".to_string() },
//! ],
//! )
//! .unwrap();
//! assert_eq!(user.name, "Bob");
//!
//! let user = User::hydrate_from_new(UserId::new(), NewUser { name: "Alice".to_string() }).unwrap();
//! assert_eq!(user.name, "Alice");
//! assert!(!user.events().any_new());
//! ```
//!
//! An entity built this way is what a repository load returns: its events
//! are all persisted, recorded at [`Clock::now`].
use crate::;
/// Rebuilds an entity from an arbitrary event stream.
/// Builds an entity from its `New*` type when the repository is the id
/// source: the test picks the id.
/// Builds an entity from its `New*` type when the caller is the id source:
/// the id is in the `New*` value.