1use naia_serde::{BitReader, BitWrite, ConstBitLength, Serde, SerdeErr, UnsignedVariableInteger};
2
3use crate::{EntityDoesNotExistError, GlobalEntity, LocalEntityAndGlobalEntityConverter};
4
5#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
7pub enum OwnedLocalEntity {
8 Host {
10 id: u16,
12 is_static: bool,
14 },
15 Remote {
17 id: u16,
19 is_static: bool,
21 },
22}
23
24impl OwnedLocalEntity {
25 pub fn new_host(id: HostEntity) -> Self {
27 Self::Host { id: id.value(), is_static: false }
28 }
29
30 pub fn new_host_dynamic(id: u16) -> Self {
32 Self::Host { id, is_static: false }
33 }
34
35 pub fn new_host_static(id: u16) -> Self {
37 Self::Host { id, is_static: true }
38 }
39
40 pub fn new_remote(id: RemoteEntity) -> Self {
42 Self::Remote { id: id.value(), is_static: id.is_static() }
43 }
44
45 pub fn new_remote_dynamic(id: u16) -> Self {
47 Self::Remote { id, is_static: false }
48 }
49
50 pub fn new_remote_static(id: u16) -> Self {
52 Self::Remote { id, is_static: true }
53 }
54
55 pub fn is_host(&self) -> bool {
57 match self {
58 Self::Host { .. } => true,
59 Self::Remote { .. } => false,
60 }
61 }
62
63 pub fn is_remote(&self) -> bool {
65 !self.is_host()
66 }
67
68 pub fn is_static(&self) -> bool {
70 match self {
71 Self::Host { is_static, .. } => *is_static,
72 Self::Remote { is_static, .. } => *is_static,
73 }
74 }
75
76 pub fn id(&self) -> u16 {
78 match self {
79 Self::Host { id, .. } | Self::Remote { id, .. } => *id,
80 }
81 }
82
83 pub fn ser(&self, writer: &mut dyn BitWrite) {
85 match self {
86 Self::Host { id, is_static } => {
87 true.ser(writer);
88 is_static.ser(writer);
89 UnsignedVariableInteger::<7>::new(*id).ser(writer);
90 }
91 Self::Remote { id, is_static } => {
92 false.ser(writer);
93 is_static.ser(writer);
94 UnsignedVariableInteger::<7>::new(*id).ser(writer);
95 }
96 }
97 }
98
99 pub fn de(reader: &mut BitReader) -> Result<Self, SerdeErr> {
101 let is_host = bool::de(reader)?;
102 let is_static = bool::de(reader)?;
103 let id = UnsignedVariableInteger::<7>::de(reader)?.get() as u16;
104 if is_host {
105 Ok(Self::Host { id, is_static })
106 } else {
107 Ok(Self::Remote { id, is_static })
108 }
109 }
110
111 pub fn bit_length(&self) -> u32 {
113 match self {
114 Self::Host { id, .. } | Self::Remote { id, .. } => {
115 bool::const_bit_length() + bool::const_bit_length() + UnsignedVariableInteger::<7>::new(*id).bit_length()
118 }
119 }
120 }
121
122 pub(crate) fn convert_to_global(
123 &self,
124 converter: &dyn LocalEntityAndGlobalEntityConverter,
125 ) -> Result<GlobalEntity, EntityDoesNotExistError> {
126 match self {
127 OwnedLocalEntity::Host { id, is_static: true } => {
128 converter.static_host_entity_to_global_entity(&HostEntity::new(*id))
129 }
130 OwnedLocalEntity::Host { id, is_static: false } => {
131 converter.host_entity_to_global_entity(&HostEntity::new(*id))
132 }
133 OwnedLocalEntity::Remote { id, is_static } => {
134 let remote = if *is_static {
135 RemoteEntity::new_static(*id)
136 } else {
137 RemoteEntity::new(*id)
138 };
139 converter.remote_entity_to_global_entity(&remote)
140 }
141 }
142 }
143
144 pub(crate) fn take_remote(&self) -> RemoteEntity {
145 let OwnedLocalEntity::Remote { id, is_static } = self else {
146 panic!("Expected RemoteEntity")
147 };
148 if *is_static { RemoteEntity::new_static(*id) } else { RemoteEntity::new(*id) }
149 }
150
151 pub(crate) fn to_reversed(self) -> OwnedLocalEntity {
152 match self {
153 OwnedLocalEntity::Host { id, is_static } => OwnedLocalEntity::Remote { id, is_static },
154 OwnedLocalEntity::Remote { id, is_static } => OwnedLocalEntity::Host { id, is_static },
155 }
156 }
157
158 pub fn host(&self) -> HostEntity {
160 match self {
161 OwnedLocalEntity::Host { id, is_static } => {
162 if *is_static { HostEntity::new_static(*id) } else { HostEntity::new(*id) }
163 }
164 OwnedLocalEntity::Remote { .. } => panic!("Expected OwnedLocalEntity::Host, found OwnedLocalEntity::Remote"),
165 }
166 }
167
168 pub fn remote(&self) -> RemoteEntity {
170 match self {
171 OwnedLocalEntity::Remote { id, is_static } => {
172 if *is_static { RemoteEntity::new_static(*id) } else { RemoteEntity::new(*id) }
173 }
174 OwnedLocalEntity::Host { .. } => panic!("Expected OwnedLocalEntity::Remote, found OwnedLocalEntity::Host"),
175 }
176 }
177}
178
179#[derive(Copy, Eq, Hash, Clone, PartialEq, Debug)]
182pub struct HostEntity {
183 id: u16,
184 is_static: bool,
185}
186
187impl HostEntity {
188 pub fn new(id: u16) -> Self {
190 Self { id, is_static: false }
191 }
192
193 pub fn new_static(id: u16) -> Self {
195 Self { id, is_static: true }
196 }
197
198 pub fn value(&self) -> u16 {
200 self.id
201 }
202
203 pub fn is_static(&self) -> bool {
205 self.is_static
206 }
207
208 pub fn to_remote(self) -> RemoteEntity {
210 if self.is_static { RemoteEntity::new_static(self.id) } else { RemoteEntity::new(self.id) }
211 }
212
213 pub fn ser(&self, writer: &mut dyn BitWrite) {
215 UnsignedVariableInteger::<7>::new(self.value()).ser(writer);
216 }
217
218 pub fn de(reader: &mut BitReader) -> Result<Self, SerdeErr> {
220 let value = UnsignedVariableInteger::<7>::de(reader)?.get();
221 Ok(Self { id: value as u16, is_static: false }) }
223
224 pub fn bit_length(&self) -> u32 {
226 UnsignedVariableInteger::<7>::new(self.value()).bit_length()
227 }
228
229 pub fn copy_to_owned(&self) -> OwnedLocalEntity {
231 OwnedLocalEntity::Host { id: self.value(), is_static: self.is_static }
232 }
233
234 pub fn copy_to_owned_dynamic(&self) -> OwnedLocalEntity {
236 OwnedLocalEntity::Host { id: self.value(), is_static: false }
237 }
238
239 pub fn copy_to_owned_static(&self) -> OwnedLocalEntity {
241 OwnedLocalEntity::Host { id: self.value(), is_static: true }
242 }
243}
244
245#[derive(Copy, Eq, Hash, Clone, PartialEq, Debug)]
247pub struct RemoteEntity {
248 id: u16,
249 is_static: bool,
250}
251
252impl RemoteEntity {
253 pub fn new(id: u16) -> Self {
255 Self { id, is_static: false }
256 }
257
258 pub fn new_static(id: u16) -> Self {
260 Self { id, is_static: true }
261 }
262
263 pub fn value(&self) -> u16 {
265 self.id
266 }
267
268 pub fn is_static(&self) -> bool {
270 self.is_static
271 }
272
273 pub fn to_host(self) -> HostEntity {
275 if self.is_static { HostEntity::new_static(self.id) } else { HostEntity::new(self.id) }
276 }
277
278 pub fn ser(&self, writer: &mut dyn BitWrite) {
280 UnsignedVariableInteger::<7>::new(self.value()).ser(writer);
281 }
282
283 pub fn de(reader: &mut BitReader) -> Result<Self, SerdeErr> {
285 let value = UnsignedVariableInteger::<7>::de(reader)?.get();
286 Ok(Self { id: value as u16, is_static: false })
287 }
288
289 pub fn copy_to_owned(&self) -> OwnedLocalEntity {
291 OwnedLocalEntity::Remote { id: self.id, is_static: self.is_static }
292 }
293}