source2_demo/entity/field/
value.rs

1use crate::error::FieldValueError;
2
3/// Special type for [`Entity`](crate::Entity) field value that can be converted
4/// into Rust type using `try_into`.
5#[derive(Debug, Clone, PartialEq)]
6pub enum FieldValue {
7    Boolean(bool),
8    String(String),
9    Float(f32),
10
11    Vector2D([f32; 2]),
12    Vector3D([f32; 3]),
13    Vector4D([f32; 4]),
14
15    Signed8(i8),
16    Signed16(i16),
17    Signed32(i32),
18    Signed64(i64),
19
20    Unsigned8(u8),
21    Unsigned16(u16),
22    Unsigned32(u32),
23    Unsigned64(u64),
24}
25
26impl TryInto<String> for FieldValue {
27    type Error = FieldValueError;
28
29    fn try_into(self) -> Result<String, FieldValueError> {
30        if let FieldValue::String(x) = self {
31            Ok(x)
32        } else {
33            Err(FieldValueError::ConversionError(
34                format!("{:?}", self),
35                "String".to_string(),
36            ))
37        }
38    }
39}
40
41impl TryInto<String> for &FieldValue {
42    type Error = FieldValueError;
43
44    fn try_into(self) -> Result<String, FieldValueError> {
45        if let FieldValue::String(x) = self {
46            Ok(x.to_owned())
47        } else {
48            Err(FieldValueError::ConversionError(
49                format!("{:?}", self),
50                "String".to_string(),
51            ))
52        }
53    }
54}
55
56impl TryInto<[f32; 2]> for FieldValue {
57    type Error = FieldValueError;
58
59    fn try_into(self) -> Result<[f32; 2], FieldValueError> {
60        if let FieldValue::Vector2D(x) = self {
61            Ok(x)
62        } else {
63            Err(FieldValueError::ConversionError(
64                format!("{:?}", self),
65                "[f32; 2]".to_string(),
66            ))
67        }
68    }
69}
70
71impl TryInto<[f32; 2]> for &FieldValue {
72    type Error = FieldValueError;
73
74    fn try_into(self) -> Result<[f32; 2], FieldValueError> {
75        if let FieldValue::Vector2D(x) = self {
76            Ok(*x)
77        } else {
78            Err(FieldValueError::ConversionError(
79                format!("{:?}", self),
80                "[f32; 2]".to_string(),
81            ))
82        }
83    }
84}
85
86impl TryInto<(f32, f32)> for FieldValue {
87    type Error = FieldValueError;
88
89    fn try_into(self) -> Result<(f32, f32), FieldValueError> {
90        if let FieldValue::Vector2D(x) = self {
91            Ok(x.into())
92        } else {
93            Err(FieldValueError::ConversionError(
94                format!("{:?}", self),
95                "(f32, f32)".to_string(),
96            ))
97        }
98    }
99}
100
101impl TryInto<(f32, f32)> for &FieldValue {
102    type Error = FieldValueError;
103
104    fn try_into(self) -> Result<(f32, f32), FieldValueError> {
105        if let FieldValue::Vector2D(x) = self {
106            Ok((*x).into())
107        } else {
108            Err(FieldValueError::ConversionError(
109                format!("{:?}", self),
110                "(f32, f32)".to_string(),
111            ))
112        }
113    }
114}
115
116impl TryInto<[f32; 3]> for FieldValue {
117    type Error = FieldValueError;
118
119    fn try_into(self) -> Result<[f32; 3], FieldValueError> {
120        if let FieldValue::Vector3D(x) = self {
121            Ok(x)
122        } else {
123            Err(FieldValueError::ConversionError(
124                format!("{:?}", self),
125                "[f32; 3]".to_string(),
126            ))
127        }
128    }
129}
130
131impl TryInto<[f32; 3]> for &FieldValue {
132    type Error = FieldValueError;
133
134    fn try_into(self) -> Result<[f32; 3], FieldValueError> {
135        if let FieldValue::Vector3D(x) = self {
136            Ok(*x)
137        } else {
138            Err(FieldValueError::ConversionError(
139                format!("{:?}", self),
140                "[f32; 3]".to_string(),
141            ))
142        }
143    }
144}
145
146impl TryInto<(f32, f32, f32)> for FieldValue {
147    type Error = FieldValueError;
148
149    fn try_into(self) -> Result<(f32, f32, f32), FieldValueError> {
150        if let FieldValue::Vector3D(x) = self {
151            Ok(x.into())
152        } else {
153            Err(FieldValueError::ConversionError(
154                format!("{:?}", self),
155                "(f32, f32, f32)".to_string(),
156            ))
157        }
158    }
159}
160
161impl TryInto<(f32, f32, f32)> for &FieldValue {
162    type Error = FieldValueError;
163
164    fn try_into(self) -> Result<(f32, f32, f32), FieldValueError> {
165        if let FieldValue::Vector3D(x) = self {
166            Ok((*x).into())
167        } else {
168            Err(FieldValueError::ConversionError(
169                format!("{:?}", self),
170                "(f32, f32, f32)".to_string(),
171            ))
172        }
173    }
174}
175
176impl TryInto<[f32; 4]> for FieldValue {
177    type Error = FieldValueError;
178
179    fn try_into(self) -> Result<[f32; 4], FieldValueError> {
180        if let FieldValue::Vector4D(x) = self {
181            Ok(x)
182        } else {
183            Err(FieldValueError::ConversionError(
184                format!("{:?}", self),
185                "[f32; 4]".to_string(),
186            ))
187        }
188    }
189}
190
191impl TryInto<[f32; 4]> for &FieldValue {
192    type Error = FieldValueError;
193
194    fn try_into(self) -> Result<[f32; 4], FieldValueError> {
195        if let FieldValue::Vector4D(x) = self {
196            Ok(*x)
197        } else {
198            Err(FieldValueError::ConversionError(
199                format!("{:?}", self),
200                "[f32; 4]".to_string(),
201            ))
202        }
203    }
204}
205
206impl TryInto<(f32, f32, f32, f32)> for FieldValue {
207    type Error = FieldValueError;
208
209    fn try_into(self) -> Result<(f32, f32, f32, f32), FieldValueError> {
210        if let FieldValue::Vector4D(x) = self {
211            Ok(x.into())
212        } else {
213            Err(FieldValueError::ConversionError(
214                format!("{:?}", self),
215                "(f32, f32, f32, f32)".to_string(),
216            ))
217        }
218    }
219}
220
221impl TryInto<(f32, f32, f32, f32)> for &FieldValue {
222    type Error = FieldValueError;
223
224    fn try_into(self) -> Result<(f32, f32, f32, f32), FieldValueError> {
225        if let FieldValue::Vector4D(x) = self {
226            Ok((*x).into())
227        } else {
228            Err(FieldValueError::ConversionError(
229                format!("{:?}", self),
230                "(f32, f32, f32, f32)".to_string(),
231            ))
232        }
233    }
234}
235
236impl TryInto<Vec<f32>> for FieldValue {
237    type Error = FieldValueError;
238
239    fn try_into(self) -> Result<Vec<f32>, FieldValueError> {
240        match self {
241            FieldValue::Vector2D(x) => Ok(x.to_vec()),
242            FieldValue::Vector3D(x) => Ok(x.to_vec()),
243            FieldValue::Vector4D(x) => Ok(x.to_vec()),
244            _ => Err(FieldValueError::ConversionError(
245                format!("{:?}", self),
246                "Vec<f32>".to_string(),
247            )),
248        }
249    }
250}
251
252impl TryInto<Vec<f32>> for &FieldValue {
253    type Error = FieldValueError;
254
255    fn try_into(self) -> Result<Vec<f32>, FieldValueError> {
256        match self {
257            FieldValue::Vector2D(x) => Ok(x.to_vec()),
258            FieldValue::Vector3D(x) => Ok(x.to_vec()),
259            FieldValue::Vector4D(x) => Ok(x.to_vec()),
260            _ => Err(FieldValueError::ConversionError(
261                format!("{:?}", self),
262                "Vec<f32>".to_string(),
263            )),
264        }
265    }
266}
267
268impl TryInto<f32> for FieldValue {
269    type Error = FieldValueError;
270
271    fn try_into(self) -> Result<f32, FieldValueError> {
272        if let FieldValue::Float(x) = self {
273            Ok(x)
274        } else {
275            Err(FieldValueError::ConversionError(
276                format!("{:?}", self),
277                "f32".to_string(),
278            ))
279        }
280    }
281}
282
283impl TryInto<f32> for &FieldValue {
284    type Error = FieldValueError;
285
286    fn try_into(self) -> Result<f32, FieldValueError> {
287        if let FieldValue::Float(x) = self {
288            Ok(*x)
289        } else {
290            Err(FieldValueError::ConversionError(
291                format!("{:?}", self),
292                "f32".to_string(),
293            ))
294        }
295    }
296}
297
298impl TryInto<bool> for FieldValue {
299    type Error = FieldValueError;
300
301    fn try_into(self) -> Result<bool, FieldValueError> {
302        if let FieldValue::Boolean(x) = self {
303            Ok(x)
304        } else {
305            Err(FieldValueError::ConversionError(
306                format!("{:?}", self),
307                "bool".to_string(),
308            ))
309        }
310    }
311}
312
313impl TryInto<bool> for &FieldValue {
314    type Error = FieldValueError;
315
316    fn try_into(self) -> Result<bool, FieldValueError> {
317        if let FieldValue::Boolean(x) = self {
318            Ok(*x)
319        } else {
320            Err(FieldValueError::ConversionError(
321                format!("{:?}", self),
322                "bool".to_string(),
323            ))
324        }
325    }
326}
327
328macro_rules! impl_try_into_for_integers {
329    ($target:ty) => {
330        impl TryInto<$target> for FieldValue {
331            type Error = FieldValueError;
332
333            fn try_into(self) -> Result<$target, FieldValueError> {
334                match self {
335                    // EntityFieldType::Boolean(x) => Ok((x == 1) as $target),
336                    FieldValue::Signed8(x) => {
337                        Ok(TryInto::<$target>::try_into(x).map_err(|_| {
338                            FieldValueError::ConversionError(
339                                format!("{:?}", x),
340                                stringify!($target).to_string(),
341                            )
342                        })?)
343                    }
344                    FieldValue::Signed16(x) => {
345                        Ok(TryInto::<$target>::try_into(x).map_err(|_| {
346                            FieldValueError::ConversionError(
347                                format!("{:?}", x),
348                                stringify!($target).to_string(),
349                            )
350                        })?)
351                    }
352                    FieldValue::Signed32(x) => {
353                        Ok(TryInto::<$target>::try_into(x).map_err(|_| {
354                            FieldValueError::ConversionError(
355                                format!("{:?}", x),
356                                stringify!($target).to_string(),
357                            )
358                        })?)
359                    }
360                    FieldValue::Signed64(x) => {
361                        Ok(TryInto::<$target>::try_into(x).map_err(|_| {
362                            FieldValueError::ConversionError(
363                                format!("{:?}", x),
364                                stringify!($target).to_string(),
365                            )
366                        })?)
367                    }
368                    FieldValue::Unsigned8(x) => {
369                        Ok(TryInto::<$target>::try_into(x).map_err(|_| {
370                            FieldValueError::ConversionError(
371                                format!("{:?}", x),
372                                stringify!($target).to_string(),
373                            )
374                        })?)
375                    }
376                    FieldValue::Unsigned16(x) => {
377                        Ok(TryInto::<$target>::try_into(x).map_err(|_| {
378                            FieldValueError::ConversionError(
379                                format!("{:?}", x),
380                                stringify!($target).to_string(),
381                            )
382                        })?)
383                    }
384                    FieldValue::Unsigned32(x) => {
385                        Ok(TryInto::<$target>::try_into(x).map_err(|_| {
386                            FieldValueError::ConversionError(
387                                format!("{:?}", x),
388                                stringify!($target).to_string(),
389                            )
390                        })?)
391                    }
392                    FieldValue::Unsigned64(x) => {
393                        Ok(TryInto::<$target>::try_into(x).map_err(|_| {
394                            FieldValueError::ConversionError(
395                                format!("{:?}", x),
396                                stringify!($target).to_string(),
397                            )
398                        })?)
399                    }
400                    FieldValue::Float(x) => Ok(x as $target),
401                    _ => Err(FieldValueError::ConversionError(
402                        format!("{:?}", self),
403                        stringify!($target).to_string(),
404                    )),
405                }
406            }
407        }
408
409        impl TryInto<$target> for &FieldValue {
410            type Error = FieldValueError;
411
412            fn try_into(self) -> Result<$target, FieldValueError> {
413                match self {
414                    // EntityFieldType::Boolean(x) => Ok(x == 1 as $target),
415                    FieldValue::Signed8(x) => {
416                        Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
417                            FieldValueError::ConversionError(
418                                format!("{:?}", x),
419                                stringify!($target).to_string(),
420                            )
421                        })?)
422                    }
423                    FieldValue::Signed16(x) => {
424                        Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
425                            FieldValueError::ConversionError(
426                                format!("{:?}", x),
427                                stringify!($target).to_string(),
428                            )
429                        })?)
430                    }
431                    FieldValue::Signed32(x) => {
432                        Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
433                            FieldValueError::ConversionError(
434                                format!("{:?}", x),
435                                stringify!($target).to_string(),
436                            )
437                        })?)
438                    }
439                    FieldValue::Signed64(x) => {
440                        Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
441                            FieldValueError::ConversionError(
442                                format!("{:?}", x),
443                                stringify!($target).to_string(),
444                            )
445                        })?)
446                    }
447                    FieldValue::Unsigned8(x) => {
448                        Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
449                            FieldValueError::ConversionError(
450                                format!("{:?}", x),
451                                stringify!($target).to_string(),
452                            )
453                        })?)
454                    }
455                    FieldValue::Unsigned16(x) => {
456                        Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
457                            FieldValueError::ConversionError(
458                                format!("{:?}", x),
459                                stringify!($target).to_string(),
460                            )
461                        })?)
462                    }
463                    FieldValue::Unsigned32(x) => {
464                        Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
465                            FieldValueError::ConversionError(
466                                format!("{:?}", x),
467                                stringify!($target).to_string(),
468                            )
469                        })?)
470                    }
471                    FieldValue::Unsigned64(x) => {
472                        Ok(TryInto::<$target>::try_into(*x).map_err(|_| {
473                            FieldValueError::ConversionError(
474                                format!("{:?}", x),
475                                stringify!($target).to_string(),
476                            )
477                        })?)
478                    }
479                    FieldValue::Float(x) => Ok(*x as $target),
480                    _ => Err(FieldValueError::ConversionError(
481                        format!("{:?}", self),
482                        stringify!($target).to_string(),
483                    )),
484                }
485            }
486        }
487    };
488}
489
490impl_try_into_for_integers!(i8);
491impl_try_into_for_integers!(i16);
492impl_try_into_for_integers!(i32);
493impl_try_into_for_integers!(i64);
494impl_try_into_for_integers!(i128);
495impl_try_into_for_integers!(u8);
496impl_try_into_for_integers!(u16);
497impl_try_into_for_integers!(u32);
498impl_try_into_for_integers!(u64);
499impl_try_into_for_integers!(u128);
500impl_try_into_for_integers!(usize);
501impl_try_into_for_integers!(isize);
502
503#[allow(dead_code)]
504impl FieldValue {
505    #[inline]
506    pub(crate) fn as_string(&self) -> String {
507        if let FieldValue::String(s) = self {
508            s.to_string()
509        } else {
510            panic!("Tried to read as String, Found {:?}", self);
511        }
512    }
513
514    #[inline]
515    pub(crate) fn as_bool(&self) -> bool {
516        if let FieldValue::Boolean(b) = self {
517            *b
518        } else {
519            panic!("Tried to read as Boolean, Found {:?}", self);
520        }
521    }
522
523    #[inline]
524    pub(crate) fn as_float(&self) -> f32 {
525        if let FieldValue::Float(f) = self {
526            *f
527        } else {
528            panic!("Tried to read as Float, Found {:?}", self);
529        }
530    }
531
532    #[inline]
533    pub(crate) fn as_vector2d(&self) -> &[f32; 2] {
534        if let FieldValue::Vector2D(v) = self {
535            v
536        } else {
537            panic!("Tried to read as Vector2D, Found {:?}", self);
538        }
539    }
540
541    #[inline]
542    pub(crate) fn as_vector(&self) -> &[f32; 3] {
543        if let FieldValue::Vector3D(v) = self {
544            v
545        } else {
546            panic!("Tried to read as Vector3D, Found {:?}", self);
547        }
548    }
549
550    #[inline]
551    pub(crate) fn as_vector4d(&self) -> &[f32; 4] {
552        if let FieldValue::Vector4D(v) = self {
553            v
554        } else {
555            panic!("Tried to read as Vector4D, Found {:?}", self);
556        }
557    }
558}