Skip to main content

frclib_core/value/
trait_impls.rs

1use crate::value::{
2    error::{CastErrorReason, FrcValueCastError},
3    FrcTimestampedValue, FrcType, FrcValue,
4    traits::StaticallyFrcTyped
5};
6
7macro_rules! static_type {
8    ($type:ty, $variant:ident) => {
9        impl StaticallyFrcTyped for $type {
10            const TYPE: FrcType = FrcType::$variant;
11        }
12    };
13}
14
15impl From<f64> for FrcValue {
16    fn from(v: f64) -> Self {
17        Self::Double(v)
18    }
19}
20static_type!(f64, Double);
21impl From<f32> for FrcValue {
22    fn from(v: f32) -> Self {
23        Self::Float(v)
24    }
25}
26static_type!(f32, Float);
27impl From<i64> for FrcValue {
28    fn from(v: i64) -> Self {
29        Self::Int(v)
30    }
31}
32static_type!(i64, Int);
33impl From<i32> for FrcValue {
34    fn from(v: i32) -> Self {
35        Self::Int(i64::from(v))
36    }
37}
38static_type!(i32, Int);
39impl From<i16> for FrcValue {
40    fn from(v: i16) -> Self {
41        Self::Int(i64::from(v))
42    }
43}
44static_type!(i16, Int);
45impl From<i8> for FrcValue {
46    fn from(v: i8) -> Self {
47        Self::Int(i64::from(v))
48    }
49}
50static_type!(i8, Int);
51impl TryFrom<u64> for FrcValue {
52    type Error = FrcValueCastError;
53
54    fn try_from(value: u64) -> Result<Self, Self::Error> {
55        Ok(Self::Int(i64::try_from(value).map_err(|_| {
56            FrcValueCastError::InvalidCastFrom(
57                stringify!(u64),
58                FrcType::Int,
59                CastErrorReason::Overflow,
60            )
61        })?))
62    }
63}
64impl From<u32> for FrcValue {
65    fn from(v: u32) -> Self {
66        Self::Int(i64::from(v))
67    }
68}
69static_type!(u32, Int);
70impl From<u16> for FrcValue {
71    fn from(v: u16) -> Self {
72        Self::Int(i64::from(v))
73    }
74}
75static_type!(u16, Int);
76impl From<u8> for FrcValue {
77    fn from(v: u8) -> Self {
78        Self::Int(i64::from(v))
79    }
80}
81static_type!(u8, Int);
82impl From<bool> for FrcValue {
83    fn from(v: bool) -> Self {
84        Self::Boolean(v)
85    }
86}
87static_type!(bool, Boolean);
88impl From<String> for FrcValue {
89    fn from(v: String) -> Self {
90        Self::String(Box::from(v))
91    }
92}
93static_type!(String, String);
94impl From<Box<str>> for FrcValue {
95    fn from(v: Box<str>) -> Self {
96        Self::String(v)
97    }
98}
99static_type!(Box<str>, String);
100impl From<&str> for FrcValue {
101    fn from(v: &str) -> Self {
102        Self::String(Box::from(v))
103    }
104}
105static_type!(&str, String);
106impl From<Vec<bool>> for FrcValue {
107    fn from(v: Vec<bool>) -> Self {
108        Self::BooleanArray(v.into_boxed_slice())
109    }
110}
111static_type!(Vec<bool>, BooleanArray);
112impl From<Box<[bool]>> for FrcValue {
113    fn from(v: Box<[bool]>) -> Self {
114        Self::BooleanArray(v)
115    }
116}
117static_type!(Box<[bool]>, BooleanArray);
118impl From<Vec<i64>> for FrcValue {
119    fn from(v: Vec<i64>) -> Self {
120        Self::IntArray(v.into_boxed_slice())
121    }
122}
123static_type!(Vec<i64>, IntArray);
124impl From<Box<[i64]>> for FrcValue {
125    fn from(v: Box<[i64]>) -> Self {
126        Self::IntArray(v)
127    }
128}
129static_type!(Box<[i64]>, IntArray);
130impl From<Vec<i32>> for FrcValue {
131    fn from(v: Vec<i32>) -> Self {
132        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
133    }
134}
135static_type!(Vec<i32>, IntArray);
136impl From<Box<[i32]>> for FrcValue {
137    fn from(v: Box<[i32]>) -> Self {
138        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
139    }
140}
141static_type!(Box<[i32]>, IntArray);
142impl From<Vec<i16>> for FrcValue {
143    fn from(v: Vec<i16>) -> Self {
144        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
145    }
146}
147static_type!(Vec<i16>, IntArray);
148impl From<Box<[i16]>> for FrcValue {
149    fn from(v: Box<[i16]>) -> Self {
150        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
151    }
152}
153static_type!(Box<[i16]>, IntArray);
154impl From<Vec<i8>> for FrcValue {
155    fn from(v: Vec<i8>) -> Self {
156        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
157    }
158}
159static_type!(Vec<i8>, IntArray);
160impl From<Box<[i8]>> for FrcValue {
161    fn from(v: Box<[i8]>) -> Self {
162        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
163    }
164}
165static_type!(Box<[i8]>, IntArray);
166impl TryFrom<Vec<u64>> for FrcValue {
167    type Error = FrcValueCastError;
168    fn try_from(v: Vec<u64>) -> Result<Self, Self::Error> {
169        Ok(Self::IntArray(
170            v.into_iter()
171                .map(|v| {
172                    i64::try_from(v).map_err(|_| {
173                        FrcValueCastError::InvalidCastFrom(
174                            stringify!(u64),
175                            FrcType::Int,
176                            CastErrorReason::Overflow,
177                        )
178                    })
179                })
180                .collect::<Result<Box<[i64]>, FrcValueCastError>>()?,
181        ))
182    }
183}
184impl TryFrom<Box<[u64]>> for FrcValue {
185    type Error = FrcValueCastError;
186    fn try_from(v: Box<[u64]>) -> Result<Self, Self::Error> {
187        Ok(Self::IntArray(
188            v.iter()
189                .map(|v| {
190                    i64::try_from(*v).map_err(|_| {
191                        FrcValueCastError::InvalidCastFrom(
192                            stringify!(u64),
193                            FrcType::Int,
194                            CastErrorReason::Overflow,
195                        )
196                    })
197                })
198                .collect::<Result<Box<[i64]>, FrcValueCastError>>()?,
199        ))
200    }
201}
202impl From<Vec<u32>> for FrcValue {
203    fn from(v: Vec<u32>) -> Self {
204        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
205    }
206}
207static_type!(Vec<u32>, IntArray);
208impl From<Box<[u32]>> for FrcValue {
209    fn from(v: Box<[u32]>) -> Self {
210        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
211    }
212}
213static_type!(Box<[u32]>, IntArray);
214impl From<Vec<u16>> for FrcValue {
215    fn from(v: Vec<u16>) -> Self {
216        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
217    }
218}
219static_type!(Vec<u16>, IntArray);
220impl From<Box<[u16]>> for FrcValue {
221    fn from(v: Box<[u16]>) -> Self {
222        Self::IntArray(v.iter().map(|v| i64::from(*v)).collect())
223    }
224}
225static_type!(Box<[u16]>, IntArray);
226impl From<Vec<f32>> for FrcValue {
227    fn from(v: Vec<f32>) -> Self {
228        Self::FloatArray(v.into_boxed_slice())
229    }
230}
231static_type!(Vec<f32>, FloatArray);
232impl From<Box<[f32]>> for FrcValue {
233    fn from(v: Box<[f32]>) -> Self {
234        Self::FloatArray(v)
235    }
236}
237static_type!(Box<[f32]>, FloatArray);
238impl From<Vec<f64>> for FrcValue {
239    fn from(v: Vec<f64>) -> Self {
240        Self::DoubleArray(v.into_boxed_slice())
241    }
242}
243static_type!(Vec<f64>, DoubleArray);
244impl From<Box<[f64]>> for FrcValue {
245    fn from(v: Box<[f64]>) -> Self {
246        Self::DoubleArray(v)
247    }
248}
249static_type!(Box<[f64]>, DoubleArray);
250impl From<Vec<String>> for FrcValue {
251    fn from(v: Vec<String>) -> Self {
252        Self::StringArray(v.into_iter().map(Box::from).collect())
253    }
254}
255static_type!(Vec<String>, StringArray);
256impl From<Vec<&str>> for FrcValue {
257    fn from(v: Vec<&str>) -> Self {
258        Self::StringArray(v.iter().map(|s| Box::from(*s)).collect())
259    }
260}
261static_type!(Vec<&str>, StringArray);
262impl From<Box<[&str]>> for FrcValue {
263    fn from(v: Box<[&str]>) -> Self {
264        Self::StringArray(v.iter().map(|s| Box::from(*s)).collect())
265    }
266}
267static_type!(Box<[&str]>, StringArray);
268impl From<Vec<Box<str>>> for FrcValue {
269    fn from(v: Vec<Box<str>>) -> Self {
270        Self::StringArray(Box::from(v))
271    }
272}
273static_type!(Vec<Box<str>>, StringArray);
274impl From<Box<[Box<str>]>> for FrcValue {
275    fn from(v: Box<[Box<str>]>) -> Self {
276        Self::StringArray(v)
277    }
278}
279static_type!(Box<[Box<str>]>, StringArray);
280impl From<Box<[u8]>> for FrcValue {
281    fn from(v: Box<[u8]>) -> Self {
282        Self::Raw(v)
283    }
284}
285static_type!(Box<[u8]>, Raw);
286impl From<FrcTimestampedValue> for FrcValue {
287    fn from(v: FrcTimestampedValue) -> Self {
288        v.value
289    }
290}
291impl<T: IntoFrcValue> From<Option<T>> for FrcValue {
292    fn from(v: Option<T>) -> Self {
293        match v {
294            Some(v) => v.into_frc_value(),
295            None => Self::Void,
296        }
297    }
298}
299impl<T: StaticallyFrcTyped> StaticallyFrcTyped for Option<T> {
300    const TYPE: FrcType = T::TYPE;
301    const COULD_BE_VOID: bool = true;
302}
303
304impl<const N: usize, T> From<[T; N]> for FrcValue
305where
306    T: Send + Sync,
307    Box<[T]>: IntoFrcValue
308{
309    fn from(v: [T; N]) -> Self {
310        let boxed: Box<[T]> = Box::from(v);
311        boxed.into_frc_value()
312    }
313}
314impl<const N: usize, T> StaticallyFrcTyped for [T; N]
315where
316    T: Send + Sync,
317    Box<[T]>: StaticallyFrcTyped
318{
319    const TYPE: FrcType = <Box<[T]>>::TYPE;
320}
321
322impl TryFrom<FrcValue> for f64 {
323    type Error = FrcValueCastError;
324    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
325        match value {
326            FrcValue::Double(v) => Ok(v),
327            FrcValue::Float(v) => Ok(Self::from(v)),
328            _ => Err(FrcValueCastError::InvalidCastTo(
329                value.get_type(),
330                stringify!(f64),
331                CastErrorReason::Type,
332            )),
333        }
334    }
335}
336
337impl TryFrom<FrcValue> for f32 {
338    type Error = FrcValueCastError;
339    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
340        match value {
341            FrcValue::Double(v) => {
342                #[allow(clippy::cast_possible_truncation)]
343                let v_f32 = v as Self;
344                if v_f32.is_infinite() {
345                    if v < 0.0 {
346                        Err(FrcValueCastError::InvalidCastTo(
347                            value.get_type(),
348                            stringify!(f32),
349                            CastErrorReason::Overflow,
350                        ))
351                    } else {
352                        Err(FrcValueCastError::InvalidCastTo(
353                            value.get_type(),
354                            stringify!(f32),
355                            CastErrorReason::Underflow,
356                        ))
357                    }
358                } else {
359                    Ok(v_f32)
360                }
361            }
362            FrcValue::Float(v) => Ok(v),
363            _ => Err(FrcValueCastError::InvalidCastTo(
364                value.get_type(),
365                stringify!(f32),
366                CastErrorReason::Type,
367            )),
368        }
369    }
370}
371
372impl TryFrom<FrcValue> for i64 {
373    type Error = FrcValueCastError;
374    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
375        match value {
376            FrcValue::Int(v) => Ok(v),
377            _ => Err(FrcValueCastError::InvalidCastTo(
378                value.get_type(),
379                stringify!(i64),
380                CastErrorReason::Type,
381            )),
382        }
383    }
384}
385
386impl TryFrom<FrcValue> for i32 {
387    type Error = FrcValueCastError;
388    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
389        match value {
390            FrcValue::Int(v) => Self::try_from(v).map_err(|_| {
391                if v < 0 {
392                    FrcValueCastError::InvalidCastTo(
393                        value.get_type(),
394                        stringify!(i32),
395                        CastErrorReason::Underflow,
396                    )
397                } else {
398                    FrcValueCastError::InvalidCastTo(
399                        value.get_type(),
400                        stringify!(i32),
401                        CastErrorReason::Overflow,
402                    )
403                }
404            }),
405            _ => Err(FrcValueCastError::InvalidCastTo(
406                value.get_type(),
407                stringify!(i32),
408                CastErrorReason::Type,
409            )),
410        }
411    }
412}
413
414impl TryFrom<FrcValue> for i16 {
415    type Error = FrcValueCastError;
416    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
417        match value {
418            FrcValue::Int(v) => Self::try_from(v).map_err(|_| {
419                if v < 0 {
420                    FrcValueCastError::InvalidCastTo(
421                        value.get_type(),
422                        stringify!(i16),
423                        CastErrorReason::Underflow,
424                    )
425                } else {
426                    FrcValueCastError::InvalidCastTo(
427                        value.get_type(),
428                        stringify!(i16),
429                        CastErrorReason::Overflow,
430                    )
431                }
432            }),
433            _ => Err(FrcValueCastError::InvalidCastTo(
434                value.get_type(),
435                stringify!(i16),
436                CastErrorReason::Type,
437            )),
438        }
439    }
440}
441
442impl TryFrom<FrcValue> for i8 {
443    type Error = FrcValueCastError;
444    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
445        match value {
446            FrcValue::Int(v) => Self::try_from(v).map_err(|_| {
447                if v < 0 {
448                    FrcValueCastError::InvalidCastTo(
449                        value.get_type(),
450                        stringify!(i8),
451                        CastErrorReason::Underflow,
452                    )
453                } else {
454                    FrcValueCastError::InvalidCastTo(
455                        value.get_type(),
456                        stringify!(i8),
457                        CastErrorReason::Overflow,
458                    )
459                }
460            }),
461            _ => Err(FrcValueCastError::InvalidCastTo(
462                value.get_type(),
463                stringify!(i8),
464                CastErrorReason::Type,
465            )),
466        }
467    }
468}
469
470impl TryFrom<FrcValue> for u64 {
471    type Error = FrcValueCastError;
472    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
473        match value {
474            FrcValue::Int(v) => Self::try_from(v).map_err(|_| {
475                FrcValueCastError::InvalidCastTo(
476                    value.get_type(),
477                    stringify!(u64),
478                    CastErrorReason::Underflow,
479                )
480            }),
481            _ => Err(FrcValueCastError::InvalidCastTo(
482                value.get_type(),
483                stringify!(u64),
484                CastErrorReason::Type,
485            )),
486        }
487    }
488}
489
490impl TryFrom<FrcValue> for u32 {
491    type Error = FrcValueCastError;
492    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
493        match value {
494            FrcValue::Int(v) => Self::try_from(v).map_err(|_| {
495                if v < 0 {
496                    FrcValueCastError::InvalidCastTo(
497                        value.get_type(),
498                        stringify!(u32),
499                        CastErrorReason::Underflow,
500                    )
501                } else {
502                    FrcValueCastError::InvalidCastTo(
503                        value.get_type(),
504                        stringify!(u32),
505                        CastErrorReason::Overflow,
506                    )
507                }
508            }),
509            _ => Err(FrcValueCastError::InvalidCastTo(
510                value.get_type(),
511                stringify!(u32),
512                CastErrorReason::Type,
513            )),
514        }
515    }
516}
517
518impl TryFrom<FrcValue> for u16 {
519    type Error = FrcValueCastError;
520    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
521        match value {
522            FrcValue::Int(v) => Self::try_from(v).map_err(|_| {
523                if v < 0 {
524                    FrcValueCastError::InvalidCastTo(
525                        value.get_type(),
526                        stringify!(u16),
527                        CastErrorReason::Underflow,
528                    )
529                } else {
530                    FrcValueCastError::InvalidCastTo(
531                        value.get_type(),
532                        stringify!(u16),
533                        CastErrorReason::Overflow,
534                    )
535                }
536            }),
537            _ => Err(FrcValueCastError::InvalidCastTo(
538                value.get_type(),
539                stringify!(u16),
540                CastErrorReason::Type,
541            )),
542        }
543    }
544}
545
546impl TryFrom<FrcValue> for u8 {
547    type Error = FrcValueCastError;
548    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
549        match value {
550            FrcValue::Int(v) => Self::try_from(v).map_err(|_| {
551                if v < 0 {
552                    FrcValueCastError::InvalidCastTo(
553                        value.get_type(),
554                        stringify!(u8),
555                        CastErrorReason::Underflow,
556                    )
557                } else {
558                    FrcValueCastError::InvalidCastTo(
559                        value.get_type(),
560                        stringify!(u8),
561                        CastErrorReason::Overflow,
562                    )
563                }
564            }),
565            _ => Err(FrcValueCastError::InvalidCastTo(
566                value.get_type(),
567                stringify!(u8),
568                CastErrorReason::Type,
569            )),
570        }
571    }
572}
573
574impl TryFrom<FrcValue> for bool {
575    type Error = FrcValueCastError;
576    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
577        match value {
578            FrcValue::Boolean(v) => Ok(v),
579            _ => Err(FrcValueCastError::InvalidCastTo(
580                value.get_type(),
581                stringify!(bool),
582                CastErrorReason::Type,
583            )),
584        }
585    }
586}
587
588impl TryFrom<FrcValue> for String {
589    type Error = FrcValueCastError;
590    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
591        match value {
592            FrcValue::String(v) => Ok(v.to_string()),
593            _ => Err(FrcValueCastError::InvalidCastTo(
594                value.get_type(),
595                stringify!(String),
596                CastErrorReason::Type,
597            )),
598        }
599    }
600}
601
602impl TryFrom<FrcValue> for Box<str> {
603    type Error = FrcValueCastError;
604    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
605        match value {
606            FrcValue::String(v) => Ok(v),
607            _ => Err(FrcValueCastError::InvalidCastTo(
608                value.get_type(),
609                stringify!(Box<str>),
610                CastErrorReason::Type,
611            )),
612        }
613    }
614}
615
616impl TryFrom<FrcValue> for Vec<f64> {
617    type Error = FrcValueCastError;
618    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
619        match value {
620            FrcValue::DoubleArray(va) => Ok(Self::from(va)),
621            FrcValue::FloatArray(va) => Ok(va.iter().map(|v| f64::from(*v)).collect()),
622            _ => Err(FrcValueCastError::InvalidCastTo(
623                value.get_type(),
624                stringify!(Vec<f64>),
625                CastErrorReason::Type,
626            )),
627        }
628    }
629}
630
631impl TryFrom<FrcValue> for Vec<f32> {
632    type Error = FrcValueCastError;
633    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
634        let value_type = value.get_type();
635        match value {
636            FrcValue::DoubleArray(va) => {
637                let mut ret_vec = Self::with_capacity(va.len());
638                for v in va.iter() {
639                    if *v > f64::from(f32::MAX) {
640                        return Err(FrcValueCastError::InvalidCastTo(
641                            value_type,
642                            stringify!(Vec<f32>),
643                            CastErrorReason::Overflow,
644                        ));
645                    } else if *v < f64::from(f32::MIN) {
646                        return Err(FrcValueCastError::InvalidCastTo(
647                            value_type,
648                            stringify!(Vec<f32>),
649                            CastErrorReason::Underflow,
650                        ));
651                    }
652                    #[allow(clippy::cast_possible_truncation)]
653                    ret_vec.push(*v as f32);
654                }
655                Ok(ret_vec)
656            }
657            FrcValue::FloatArray(v) => Ok(v.into_vec()),
658            _ => Err(FrcValueCastError::InvalidCastTo(
659                value.get_type(),
660                stringify!(Vec<f32>),
661                CastErrorReason::Type,
662            )),
663        }
664    }
665}
666
667impl TryFrom<FrcValue> for Vec<i64> {
668    type Error = FrcValueCastError;
669    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
670        match value {
671            FrcValue::IntArray(va) => Ok(va.into_vec()),
672            _ => Err(FrcValueCastError::InvalidCastTo(
673                value.get_type(),
674                stringify!(Vec<i64>),
675                CastErrorReason::Type,
676            )),
677        }
678    }
679}
680
681impl TryFrom<FrcValue> for Vec<i32> {
682    type Error = FrcValueCastError;
683    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
684        match value {
685            FrcValue::IntArray(ref va) => {
686                let mut ret_vec = Self::with_capacity(va.len());
687                for v in va.iter() {
688                    ret_vec.push(i32::try_from(*v).map_err(|_| {
689                        if *v < 0 {
690                            FrcValueCastError::InvalidCastTo(
691                                value.get_type(),
692                                stringify!(Vec<i32>),
693                                CastErrorReason::Underflow,
694                            )
695                        } else {
696                            FrcValueCastError::InvalidCastTo(
697                                value.get_type(),
698                                stringify!(Vec<i32>),
699                                CastErrorReason::Overflow,
700                            )
701                        }
702                    })?);
703                }
704                Ok(ret_vec)
705            }
706            _ => Err(FrcValueCastError::InvalidCastTo(
707                value.get_type(),
708                stringify!(Vec<i32>),
709                CastErrorReason::Type,
710            )),
711        }
712    }
713}
714
715impl TryFrom<FrcValue> for Vec<i16> {
716    type Error = FrcValueCastError;
717    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
718        match value {
719            FrcValue::IntArray(ref va) => {
720                let mut ret_vec = Self::with_capacity(va.len());
721                for v in va.iter() {
722                    ret_vec.push(i16::try_from(*v).map_err(|_| {
723                        if *v < 0 {
724                            FrcValueCastError::InvalidCastTo(
725                                value.get_type(),
726                                stringify!(Vec<i16>),
727                                CastErrorReason::Underflow,
728                            )
729                        } else {
730                            FrcValueCastError::InvalidCastTo(
731                                value.get_type(),
732                                stringify!(Vec<i16>),
733                                CastErrorReason::Overflow,
734                            )
735                        }
736                    })?);
737                }
738                Ok(ret_vec)
739            }
740            _ => Err(FrcValueCastError::InvalidCastTo(
741                value.get_type(),
742                stringify!(Vec<i16>),
743                CastErrorReason::Type,
744            )),
745        }
746    }
747}
748
749impl TryFrom<FrcValue> for Vec<i8> {
750    type Error = FrcValueCastError;
751    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
752        match value {
753            FrcValue::IntArray(ref va) => {
754                let mut ret_vec = Self::with_capacity(va.len());
755                for v in va.iter() {
756                    ret_vec.push(i8::try_from(*v).map_err(|_| {
757                        if *v < 0 {
758                            FrcValueCastError::InvalidCastTo(
759                                value.get_type(),
760                                stringify!(Vec<i8>),
761                                CastErrorReason::Underflow,
762                            )
763                        } else {
764                            FrcValueCastError::InvalidCastTo(
765                                value.get_type(),
766                                stringify!(Vec<i8>),
767                                CastErrorReason::Overflow,
768                            )
769                        }
770                    })?);
771                }
772                Ok(ret_vec)
773            }
774            _ => Err(FrcValueCastError::InvalidCastTo(
775                value.get_type(),
776                stringify!(Vec<i8>),
777                CastErrorReason::Type,
778            )),
779        }
780    }
781}
782
783impl TryFrom<FrcValue> for Vec<u64> {
784    type Error = FrcValueCastError;
785    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
786        match value {
787            FrcValue::IntArray(ref va) => {
788                let mut ret_vec = Self::with_capacity(va.len());
789                for v in va.iter() {
790                    ret_vec.push(u64::try_from(*v).map_err(|_| {
791                        if *v < 0 {
792                            FrcValueCastError::InvalidCastTo(
793                                value.get_type(),
794                                stringify!(Vec<u64>),
795                                CastErrorReason::Underflow,
796                            )
797                        } else {
798                            FrcValueCastError::InvalidCastTo(
799                                value.get_type(),
800                                stringify!(Vec<u64>),
801                                CastErrorReason::Overflow,
802                            )
803                        }
804                    })?);
805                }
806                Ok(ret_vec)
807            }
808            _ => Err(FrcValueCastError::InvalidCastTo(
809                value.get_type(),
810                stringify!(Vec<u64>),
811                CastErrorReason::Type,
812            )),
813        }
814    }
815}
816
817impl TryFrom<FrcValue> for Vec<u32> {
818    type Error = FrcValueCastError;
819    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
820        match value {
821            FrcValue::IntArray(ref va) => {
822                let mut ret_vec = Self::with_capacity(va.len());
823                for v in va.iter() {
824                    ret_vec.push(u32::try_from(*v).map_err(|_| {
825                        if *v < 0 {
826                            FrcValueCastError::InvalidCastTo(
827                                value.get_type(),
828                                stringify!(Vec<u32>),
829                                CastErrorReason::Underflow,
830                            )
831                        } else {
832                            FrcValueCastError::InvalidCastTo(
833                                value.get_type(),
834                                stringify!(Vec<u32>),
835                                CastErrorReason::Overflow,
836                            )
837                        }
838                    })?);
839                }
840                Ok(ret_vec)
841            }
842            _ => Err(FrcValueCastError::InvalidCastTo(
843                value.get_type(),
844                stringify!(Vec<u32>),
845                CastErrorReason::Type,
846            )),
847        }
848    }
849}
850
851impl TryFrom<FrcValue> for Vec<u16> {
852    type Error = FrcValueCastError;
853    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
854        match value {
855            FrcValue::IntArray(ref va) => {
856                let mut ret_vec = Self::with_capacity(va.len());
857                for v in va.iter() {
858                    ret_vec.push(u16::try_from(*v).map_err(|_| {
859                        if *v < 0 {
860                            FrcValueCastError::InvalidCastTo(
861                                value.get_type(),
862                                stringify!(Vec<u16>),
863                                CastErrorReason::Underflow,
864                            )
865                        } else {
866                            FrcValueCastError::InvalidCastTo(
867                                value.get_type(),
868                                stringify!(Vec<u16>),
869                                CastErrorReason::Overflow,
870                            )
871                        }
872                    })?);
873                }
874                Ok(ret_vec)
875            }
876            _ => Err(FrcValueCastError::InvalidCastTo(
877                value.get_type(),
878                stringify!(Vec<u16>),
879                CastErrorReason::Type,
880            )),
881        }
882    }
883}
884
885impl TryFrom<FrcValue> for Vec<u8> {
886    type Error = FrcValueCastError;
887    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
888        match value {
889            FrcValue::IntArray(ref va) => {
890                let mut ret_vec = Self::with_capacity(va.len());
891                for v in va.iter() {
892                    ret_vec.push(u8::try_from(*v).map_err(|_| {
893                        if *v < 0 {
894                            FrcValueCastError::InvalidCastTo(
895                                value.get_type(),
896                                stringify!(Vec<u8>),
897                                CastErrorReason::Underflow,
898                            )
899                        } else {
900                            FrcValueCastError::InvalidCastTo(
901                                value.get_type(),
902                                stringify!(Vec<u8>),
903                                CastErrorReason::Overflow,
904                            )
905                        }
906                    })?);
907                }
908                Ok(ret_vec)
909            }
910            _ => Err(FrcValueCastError::InvalidCastTo(
911                value.get_type(),
912                stringify!(Vec<u8>),
913                CastErrorReason::Type,
914            )),
915        }
916    }
917}
918
919impl TryFrom<FrcValue> for Vec<bool> {
920    type Error = FrcValueCastError;
921    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
922        match value {
923            FrcValue::BooleanArray(va) => Ok(va.into_vec()),
924            _ => Err(FrcValueCastError::InvalidCastTo(
925                value.get_type(),
926                stringify!(Vec<bool>),
927                CastErrorReason::Type,
928            )),
929        }
930    }
931}
932
933impl TryFrom<FrcValue> for Vec<String> {
934    type Error = FrcValueCastError;
935    fn try_from(value: FrcValue) -> Result<Self, Self::Error> {
936        match value {
937            FrcValue::StringArray(va) => {
938                Ok(va.iter().map(std::string::ToString::to_string).collect())
939            }
940            _ => Err(FrcValueCastError::InvalidCastTo(
941                value.get_type(),
942                stringify!(Vec<String>),
943                CastErrorReason::Type,
944            )),
945        }
946    }
947}
948
949use rmpv::Value as MPValue;
950
951impl TryFrom<MPValue> for FrcValue {
952    type Error = FrcValueCastError;
953    fn try_from(value: MPValue) -> Result<Self, Self::Error> {
954        match value {
955            MPValue::Nil => Ok(Self::Void),
956            MPValue::Boolean(b) => Ok(Self::Boolean(b)),
957            MPValue::Integer(i) => Ok(Self::Int(i.as_i64().unwrap_or_default())),
958            MPValue::F32(f) => Ok(Self::Float(f)),
959            MPValue::F64(f) => Ok(Self::Double(f)),
960            MPValue::String(s) => Ok(Self::String(s.to_string().into_boxed_str())),
961            MPValue::Binary(b) => Ok(Self::Raw(b.into_boxed_slice())),
962            MPValue::Array(a) => {
963                let mut arr = Vec::with_capacity(a.len());
964                for v in a {
965                    arr.push(Self::try_from(v)?);
966                }
967                if arr.is_empty() {
968                    return Ok(Self::empty());
969                }
970                let first_type = arr[0].get_type();
971                if arr.iter().all(|v| v.get_type() == first_type) {
972                    match first_type {
973                        FrcType::Boolean => Ok(Self::BooleanArray(
974                            arr.into_iter()
975                                .map(bool::try_from)
976                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
977                        )),
978                        FrcType::Int => Ok(Self::IntArray(
979                            arr.into_iter()
980                                .map(i64::try_from)
981                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
982                        )),
983                        FrcType::Float => Ok(Self::FloatArray(
984                            arr.into_iter()
985                                .map(f32::try_from)
986                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
987                        )),
988                        FrcType::Double => Ok(Self::DoubleArray(
989                            arr.into_iter()
990                                .map(f64::try_from)
991                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
992                        )),
993                        FrcType::String => Ok(Self::StringArray(
994                            arr.into_iter()
995                                .map(|v| String::try_from(v).map(Box::from))
996                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
997                        )),
998                        any => Err(FrcValueCastError::InvalidCastTo(
999                            any,
1000                            stringify!(MPValue),
1001                            CastErrorReason::Type,
1002                        )),
1003                    }
1004                } else {
1005                    Err(FrcValueCastError::InvalidCastTo(
1006                        first_type,
1007                        stringify!(MPValue),
1008                        CastErrorReason::Type,
1009                    ))
1010                }
1011            }
1012            _ => Err(FrcValueCastError::UnrepresentableCast),
1013        }
1014    }
1015}
1016
1017impl From<FrcValue> for MPValue {
1018    fn from(value: FrcValue) -> Self {
1019        match value {
1020            FrcValue::Boolean(b) => Self::Boolean(b),
1021            FrcValue::Int(i) => Self::Integer(i.into()),
1022            FrcValue::Float(f) => Self::F32(f),
1023            FrcValue::Double(f) => Self::F64(f),
1024            FrcValue::String(s) => Self::String(s.to_string().into()),
1025            FrcValue::BooleanArray(a) => {
1026                Self::Array(a.iter().map(|v| Self::Boolean(*v)).collect::<Vec<Self>>())
1027            }
1028            FrcValue::IntArray(a) => Self::Array(
1029                a.iter()
1030                    .map(|v| Self::Integer((*v).into()))
1031                    .collect::<Vec<Self>>(),
1032            ),
1033            FrcValue::FloatArray(a) => {
1034                Self::Array(a.iter().map(|v| Self::F32(*v)).collect::<Vec<Self>>())
1035            }
1036            FrcValue::DoubleArray(a) => {
1037                Self::Array(a.iter().map(|v| Self::F64(*v)).collect::<Vec<Self>>())
1038            }
1039            FrcValue::StringArray(a) => Self::Array(
1040                a.iter()
1041                    .map(|v| Self::String(v.to_string().into()))
1042                    .collect::<Vec<Self>>(),
1043            ),
1044            FrcValue::Raw(b) => Self::Binary(b.to_vec()),
1045            _ => Self::Nil, //TODO: implement struct array conversion
1046        }
1047    }
1048}
1049
1050use serde_json::Value as JSONValue;
1051
1052use super::IntoFrcValue;
1053
1054#[allow(clippy::match_wildcard_for_single_variants)]
1055impl TryFrom<JSONValue> for FrcValue {
1056    type Error = FrcValueCastError;
1057    fn try_from(value: JSONValue) -> Result<Self, Self::Error> {
1058        match value {
1059            JSONValue::Null => Ok(Self::Void),
1060            JSONValue::Bool(b) => Ok(Self::Boolean(b)),
1061            JSONValue::Number(n) => {
1062                if n.is_i64() {
1063                    Ok(Self::Int(n.as_i64().unwrap_or_default()))
1064                } else if n.is_f64() {
1065                    Ok(Self::Double(n.as_f64().unwrap_or_default()))
1066                } else {
1067                    Err(FrcValueCastError::InvalidCastTo(
1068                        FrcType::Double,
1069                        stringify!(JSONValue),
1070                        CastErrorReason::Type,
1071                    ))
1072                }
1073            }
1074            JSONValue::String(s) => Ok(Self::String(s.into_boxed_str())),
1075            JSONValue::Array(a) => {
1076                let mut arr = Vec::with_capacity(a.len());
1077                for v in a {
1078                    arr.push(Self::try_from(v)?);
1079                }
1080                if arr.is_empty() {
1081                    return Ok(Self::empty());
1082                }
1083                let first_type = arr[0].get_type();
1084                if arr.iter().all(|v| v.get_type() == first_type) {
1085                    match first_type {
1086                        FrcType::Boolean => Ok(Self::BooleanArray(
1087                            arr.into_iter()
1088                                .map(bool::try_from)
1089                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
1090                        )),
1091                        FrcType::Int => Ok(Self::IntArray(
1092                            arr.into_iter()
1093                                .map(i64::try_from)
1094                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
1095                        )),
1096                        FrcType::Float => Ok(Self::FloatArray(
1097                            arr.into_iter()
1098                                .map(f32::try_from)
1099                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
1100                        )),
1101                        FrcType::Double => Ok(Self::DoubleArray(
1102                            arr.into_iter()
1103                                .map(f64::try_from)
1104                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
1105                        )),
1106                        FrcType::String => Ok(Self::StringArray(
1107                            arr.into_iter()
1108                                .map(|v| String::try_from(v).map(Box::from))
1109                                .collect::<Result<Box<[_]>, FrcValueCastError>>()?,
1110                        )),
1111                        any => Err(FrcValueCastError::InvalidCastTo(
1112                            any,
1113                            stringify!(JSONValue),
1114                            CastErrorReason::Type,
1115                        )),
1116                    }
1117                } else {
1118                    Err(FrcValueCastError::InvalidCastTo(
1119                        first_type,
1120                        stringify!(JSONValue),
1121                        CastErrorReason::Type,
1122                    ))
1123                }
1124            }
1125            _ => Err(FrcValueCastError::UnrepresentableCast),
1126        }
1127    }
1128}
1129
1130#[allow(clippy::fallible_impl_from, clippy::cast_sign_loss)]
1131impl From<FrcValue> for JSONValue {
1132    fn from(value: FrcValue) -> Self {
1133        match value {
1134            FrcValue::Boolean(b) => Self::Bool(b),
1135            FrcValue::Int(i) => Self::Number({
1136                if i < 0 {
1137                    serde_json::Number::from(i)
1138                } else {
1139                    serde_json::Number::from(i as u64)
1140                }
1141            }),
1142            FrcValue::Float(f) => Self::Number(
1143                serde_json::Number::from_f64(f64::from(f))
1144                    .unwrap_or_else(|| serde_json::Number::from(0)),
1145            ),
1146            FrcValue::Double(f) => Self::Number(
1147                serde_json::Number::from_f64(f).unwrap_or_else(|| serde_json::Number::from(0)),
1148            ),
1149            FrcValue::String(s) => Self::String(s.into()),
1150            FrcValue::Raw(b) => Self::Array(
1151                b.iter()
1152                    .map(|v| Self::Number((i64::from(*v)).into()))
1153                    .collect::<Vec<Self>>(),
1154            ),
1155            FrcValue::BooleanArray(a) => {
1156                Self::Array(a.iter().map(|v| Self::Bool(*v)).collect::<Vec<Self>>())
1157            }
1158            FrcValue::IntArray(a) => Self::Array(
1159                a.iter()
1160                    .map(|v| {
1161                        Self::Number({
1162                            if *v < 0 {
1163                                serde_json::Number::from(*v)
1164                            } else {
1165                                serde_json::Number::from(*v as u64)
1166                            }
1167                        })
1168                    })
1169                    .collect::<Vec<Self>>(),
1170            ),
1171            FrcValue::FloatArray(a) => Self::Array(
1172                a.iter()
1173                    .map(|v| {
1174                        Self::Number(
1175                            serde_json::Number::from_f64(f64::from(*v))
1176                                .unwrap_or_else(|| serde_json::Number::from(0)),
1177                        )
1178                    })
1179                    .collect::<Vec<Self>>(),
1180            ),
1181            FrcValue::DoubleArray(a) => Self::Array(
1182                a.iter()
1183                    .map(|v| {
1184                        Self::Number(
1185                            serde_json::Number::from_f64(*v)
1186                                .unwrap_or_else(|| serde_json::Number::from(0)),
1187                        )
1188                    })
1189                    .collect::<Vec<Self>>(),
1190            ),
1191            FrcValue::StringArray(a) => Self::Array(
1192                a.iter()
1193                    .map(|v| Self::String(v.to_string()))
1194                    .collect::<Vec<Self>>(),
1195            ),
1196            _ => Self::Null, //TODO: implement struct array conversion
1197        }
1198    }
1199}