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

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

value_types!(crate::UNIT_TYPE, () => ());
value_types!(crate::BYTE_TYPE, u8 => u8);
value_types!(crate::BOOL_TYPE, bool => bool);
value_types!(crate::CHAR_TYPE, char => char);
value_types!(crate::INTEGER_TYPE, i64 => i64);
value_types!(crate::FLOAT_TYPE, f64 => f64);
value_types!(crate::FLOAT_TYPE, f32 => f32);

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) => {
        value_types!(crate::INTEGER_TYPE, $ty => $ty);

        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)
    }
}