1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use super::ImplToFromPaxAny;
use super::Numeric;
use super::PaxAny;
use super::PaxValue;
use super::ToFromPaxAny;
use super::ToFromPaxValue;
use crate::impl_from_to_pax_any_for_from_to_pax_value;
use crate::impl_to_from_pax_value;
use crate::math::Space;
use crate::math::Transform2;
use crate::Color;
use crate::ColorChannel;
use crate::Fill;
use crate::Percent;
use crate::Rotation;
use crate::Size;
use crate::Stroke;
use crate::Transform2D;

// Primitive types
impl_to_from_pax_value!(bool, PaxValue::Bool);

impl_to_from_pax_value!(u8, PaxValue::Numeric, Numeric::U8);
impl_to_from_pax_value!(u16, PaxValue::Numeric, Numeric::U16);
impl_to_from_pax_value!(u32, PaxValue::Numeric, Numeric::U32);
impl_to_from_pax_value!(u64, PaxValue::Numeric, Numeric::U64);

impl_to_from_pax_value!(i8, PaxValue::Numeric, Numeric::I8);
impl_to_from_pax_value!(i16, PaxValue::Numeric, Numeric::I16);
impl_to_from_pax_value!(i32, PaxValue::Numeric, Numeric::I32);
impl_to_from_pax_value!(i64, PaxValue::Numeric, Numeric::I64);

impl_to_from_pax_value!(f32, PaxValue::Numeric, Numeric::F32);
impl_to_from_pax_value!(f64, PaxValue::Numeric, Numeric::F64);

impl_to_from_pax_value!(isize, PaxValue::Numeric, Numeric::ISize);
impl_to_from_pax_value!(usize, PaxValue::Numeric, Numeric::USize);

// don't allow to be serialized/deserialized sucessfully, just store it as a dyn Any
impl ImplToFromPaxAny for () {}

// for now. TBD how to handle this when we join Transform2D with Transform2 at some point
impl<F: Space, T: Space> ImplToFromPaxAny for Transform2<F, T> {}

impl_to_from_pax_value!(String, PaxValue::String);
impl_to_from_pax_value!(ColorChannel, PaxValue::ColorChannel);

// Pax internal types
impl_to_from_pax_value!(Numeric, PaxValue::Numeric);
impl_to_from_pax_value!(Size, PaxValue::Size);
impl_to_from_pax_value!(Color, PaxValue::Color);
impl_to_from_pax_value!(Transform2D, PaxValue::Transform2D);
impl_to_from_pax_value!(Rotation, PaxValue::Rotation);
impl_to_from_pax_value!(Percent, PaxValue::Percent);
impl_to_from_pax_value!(Fill, PaxValue::Fill);
impl_to_from_pax_value!(Stroke, PaxValue::Stroke);

// Pax Vec type
impl<T: ToFromPaxAny + 'static> ToFromPaxValue for Vec<T> {
    fn to_pax_value(self) -> PaxValue {
        PaxValue::Vec(self.into_iter().map(|v| v.to_pax_any()).collect::<Vec<_>>())
    }

    fn from_pax_value(pax_value: PaxValue) -> Result<Self, String> {
        match pax_value {
            PaxValue::Vec(vec) => vec
                .into_iter()
                .map(|v| T::from_pax_any(v))
                .collect::<Result<Vec<_>, _>>(),
            v => return Err(format!("can't coerce {:?} into Vec<PaxAny>", v)),
        }
    }

    fn ref_from_pax_value(_pax_value: &PaxValue) -> Result<&Self, String> {
        panic!("can't get a reference to a a container type");
    }

    fn mut_from_pax_value(_pax_value: &mut PaxValue) -> Result<&mut Self, String> {
        panic!("can't get a reference to a a container type");
    }
}

impl<T: ToFromPaxAny> ToFromPaxAny for Vec<T> {
    fn to_pax_any(self) -> PaxAny {
        PaxAny::Builtin(self.to_pax_value())
    }

    fn from_pax_any(pax_any: PaxAny) -> Result<Self, String> {
        match pax_any {
            PaxAny::Builtin(b) => <Vec<T>>::from_pax_value(b),
            PaxAny::Any(_) => panic!("can't create a vec from an any type"),
        }
    }

    fn ref_from_pax_any(_pax_any: &PaxAny) -> Result<&Self, String> {
        panic!("can't get a reference to a a container type");
    }

    fn mut_from_pax_any(_pax_any: &mut PaxAny) -> Result<&mut Self, String> {
        panic!("can't get a reference to a a container type");
    }
}