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