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