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
//! Trait implementations for primitive types.

use crate::{FromValue, Integer, ToValue, Value, VmError, VmErrorKind};

impl FromValue for () {
    fn from_value(value: Value) -> Result<Self, VmError> {
        Ok(value.into_unit()?)
    }
}

impl FromValue for u8 {
    fn from_value(value: Value) -> Result<Self, VmError> {
        Ok(value.into_byte()?)
    }
}

impl FromValue for bool {
    fn from_value(value: Value) -> Result<Self, VmError> {
        Ok(value.into_bool()?)
    }
}

impl FromValue for char {
    fn from_value(value: Value) -> Result<Self, VmError> {
        Ok(value.into_char()?)
    }
}

impl FromValue for i64 {
    fn from_value(value: Value) -> Result<Self, VmError> {
        Ok(value.into_integer()?)
    }
}

macro_rules! number_value_trait {
    ($ty:ty, $variant:ident) => {
        impl ToValue for $ty {
            fn to_value(self) -> Result<Value, VmError> {
                use std::convert::TryInto as _;

                match self.try_into() {
                    Ok(number) => Ok(Value::Integer(number)),
                    Err(..) => Err(VmError::from(VmErrorKind::IntegerToValueCoercionError {
                        from: Integer::$variant(self),
                        to: std::any::type_name::<i64>(),
                    })),
                }
            }
        }

        impl FromValue for $ty {
            fn from_value(value: Value) -> Result<Self, VmError> {
                use std::convert::TryInto as _;
                let integer = value.into_integer()?;

                match integer.try_into() {
                    Ok(number) => Ok(number),
                    Err(..) => Err(VmError::from(VmErrorKind::ValueToIntegerCoercionError {
                        from: Integer::I64(integer),
                        to: std::any::type_name::<Self>(),
                    })),
                }
            }
        }
    };
}

number_value_trait!(u32, U32);
number_value_trait!(u64, U64);
number_value_trait!(u128, U128);
number_value_trait!(usize, Usize);
number_value_trait!(i8, I8);
number_value_trait!(i32, I32);
number_value_trait!(i128, I128);
number_value_trait!(isize, Isize);

impl FromValue for f64 {
    fn from_value(value: Value) -> Result<Self, VmError> {
        Ok(value.into_float()?)
    }
}

impl ToValue for f32 {
    fn to_value(self) -> Result<Value, VmError> {
        Ok(Value::Float(self as f64))
    }
}

impl FromValue for f32 {
    fn from_value(value: Value) -> Result<Self, VmError> {
        Ok(value.into_float()? as f32)
    }
}