ddd_toolkit_core/domain/
entity.rs1use crate::domain::EntityId;
2
3pub trait Entity: Send + Sync {
21 type Id: EntityId;
23
24 fn id(&self) -> &Self::Id;
26
27 fn is_same_as(&self, other: &Self) -> bool {
30 self.id() == other.id()
31 }
32}
33
34#[cfg(test)]
35mod test {
36 use std::fmt::Display;
37
38 use crate::domain::ValueObject;
39
40 use super::*;
41
42 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
43 struct FooId(String);
44
45 impl ValueObject for FooId {}
46
47 impl Display for FooId {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 write!(f, "{}", self.0)
50 }
51 }
52
53 impl EntityId for FooId {}
54
55 struct Foo {
56 id: FooId,
57 value: String,
58 }
59
60 impl Entity for Foo {
61 type Id = FooId;
62 fn id(&self) -> &Self::Id {
63 &self.id
64 }
65 }
66
67 #[test]
68 fn id_returns_reference_to_entity_id() {
69 let foo = Foo {
70 id: FooId("foo-1".to_string()),
71 value: "value".to_string(),
72 };
73
74 assert_eq!(foo.id(), &FooId("foo-1".to_string()));
75 }
76
77 #[test]
78 fn is_same_as_returns_true_for_same_id_and_same_value() {
79 let a = Foo {
80 id: FooId("foo-1".to_string()),
81 value: "value".to_string(),
82 };
83 let b = Foo {
84 id: FooId("foo-1".to_string()),
85 value: "value".to_string(),
86 };
87
88 assert!(a.is_same_as(&b));
89 }
90
91 #[test]
92 fn is_same_as_returns_true_for_same_id_and_different_value() {
93 let a = Foo {
94 id: FooId("foo-1".to_string()),
95 value: "value-a".to_string(),
96 };
97 let b = Foo {
98 id: FooId("foo-1".to_string()),
99 value: "value-b".to_string(),
100 };
101
102 assert_ne!(a.value, b.value);
103 assert!(a.is_same_as(&b));
104 }
105
106 #[test]
107 fn is_same_as_returns_false_for_different_id_and_same_value() {
108 let a = Foo {
109 id: FooId("foo-1".to_string()),
110 value: "value".to_string(),
111 };
112 let b = Foo {
113 id: FooId("foo-2".to_string()),
114 value: "value".to_string(),
115 };
116
117 assert!(!a.is_same_as(&b));
118 }
119
120 #[test]
121 fn is_same_as_returns_true_for_self_comparison() {
122 let foo = Foo {
123 id: FooId("foo-1".to_string()),
124 value: "value".to_string(),
125 };
126
127 assert!(foo.is_same_as(&foo));
128 }
129
130 #[test]
131 fn is_same_as_returns_true_for_empty_string_ids() {
132 let a = Foo {
133 id: FooId(String::new()),
134 value: "value-a".to_string(),
135 };
136 let b = Foo {
137 id: FooId(String::new()),
138 value: "value-b".to_string(),
139 };
140
141 assert!(a.is_same_as(&b));
142 }
143
144 #[test]
145 fn entity_impl_satisfies_send_and_sync() {
146 fn assert_impl<T: Send + Sync>() {}
147 assert_impl::<Foo>();
148 }
149}