1use core::fmt;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
35#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
36pub struct EntityId(pub i32);
37
38impl fmt::Display for EntityId {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(f, "{}", self.0)
41 }
42}
43
44impl From<i32> for EntityId {
45 fn from(value: i32) -> Self {
46 Self(value)
47 }
48}
49
50impl From<EntityId> for i32 {
51 fn from(id: EntityId) -> Self {
52 id.0
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use core::hash::{Hash, Hasher};
59 use std::collections::hash_map::DefaultHasher;
60
61 use super::EntityId;
62
63 #[test]
64 fn test_equality() {
65 let a = EntityId(1);
66 let b = EntityId(1);
67 let c = EntityId(2);
68 assert_eq!(a, b);
69 assert_ne!(a, c);
70 }
71
72 #[test]
73 fn test_copy() {
74 let a = EntityId(10);
75 let b = a;
76 assert_eq!(a, b);
77 assert_eq!(a.0, 10);
78 }
79
80 #[test]
81 fn test_hash_consistency() {
82 let mut hasher_a = DefaultHasher::new();
83 EntityId(99).hash(&mut hasher_a);
84 let hash_a = hasher_a.finish();
85
86 let mut hasher_b = DefaultHasher::new();
87 EntityId(99).hash(&mut hasher_b);
88 let hash_b = hasher_b.finish();
89
90 assert_eq!(hash_a, hash_b);
91 }
92
93 #[test]
94 fn test_display() {
95 assert_eq!(EntityId(42).to_string(), "42");
96 assert_eq!(EntityId(0).to_string(), "0");
97 assert_eq!(EntityId(-1).to_string(), "-1");
98 }
99
100 #[test]
101 fn test_from_i32() {
102 let id = EntityId::from(5);
103 assert_eq!(id, EntityId(5));
104 }
105
106 #[test]
107 fn test_into_i32() {
108 let raw: i32 = i32::from(EntityId(7));
109 assert_eq!(raw, 7);
110 }
111
112 #[cfg(feature = "serde")]
113 #[test]
114 fn test_entity_id_serde_roundtrip() {
115 let id = EntityId(42);
116 let json = serde_json::to_string(&id).unwrap();
117 let deserialized: EntityId = serde_json::from_str(&json).unwrap();
118 assert_eq!(id, deserialized);
119 }
120}