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