merge 2 error enums

This commit is contained in:
Svyatoslav Nikolsky
2017-08-01 14:44:33 +03:00
parent a02fdf5836
commit 9437b7bdfc
20 changed files with 457 additions and 475 deletions

View File

@@ -1,7 +1,7 @@
use std::{i32, i64, u32, u64, f32};
use std::io;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use interpreter::Error;
use interpreter::{Error, CustomUserError};
use interpreter::variable::VariableType;
/// Runtime value.
@@ -52,15 +52,15 @@ pub trait TransmuteInto<T> {
}
/// Convert from and to little endian.
pub trait LittleEndianConvert where Self: Sized {
pub trait LittleEndianConvert<E: CustomUserError> where Self: Sized {
/// Convert to little endian buffer.
fn into_little_endian(self) -> Vec<u8>;
/// Convert from little endian buffer.
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error>;
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>>;
}
/// Arithmetic operations.
pub trait ArithmeticOps<T> {
pub trait ArithmeticOps<T, E: CustomUserError> {
/// Add two values.
fn add(self, other: T) -> T;
/// Subtract two values.
@@ -68,11 +68,11 @@ pub trait ArithmeticOps<T> {
/// Multiply two values.
fn mul(self, other: T) -> T;
/// Divide two values.
fn div(self, other: T) -> Result<T, Error>;
fn div(self, other: T) -> Result<T, Error<E>>;
}
/// Integer value.
pub trait Integer<T>: ArithmeticOps<T> {
pub trait Integer<T, E: CustomUserError>: ArithmeticOps<T, E> {
/// Counts leading zeros in the bitwise representation of the value.
fn leading_zeros(self) -> T;
/// Counts trailing zeros in the bitwise representation of the value.
@@ -84,11 +84,11 @@ pub trait Integer<T>: ArithmeticOps<T> {
/// Get right bit rotation result.
fn rotr(self, other: T) -> T;
/// Get division remainder.
fn rem(self, other: T) -> Result<T, Error>;
fn rem(self, other: T) -> Result<T, Error<E>>;
}
/// Float-point value.
pub trait Float<T>: ArithmeticOps<T> {
pub trait Float<T, E: CustomUserError>: ArithmeticOps<T, E> {
/// Get absolute value.
fn abs(self) -> T;
/// Returns the largest integer less than or equal to a number.
@@ -178,8 +178,8 @@ impl From<f64> for RuntimeValue {
}
}
impl TryInto<bool, Error> for RuntimeValue {
fn try_into(self) -> Result<bool, Error> {
impl<E> TryInto<bool, Error<E>> for RuntimeValue where E: CustomUserError {
fn try_into(self) -> Result<bool, Error<E>> {
match self {
RuntimeValue::I32(val) => Ok(val != 0),
_ => Err(Error::Value(format!("32-bit int value expected"))),
@@ -187,8 +187,8 @@ impl TryInto<bool, Error> for RuntimeValue {
}
}
impl TryInto<i32, Error> for RuntimeValue {
fn try_into(self) -> Result<i32, Error> {
impl<E> TryInto<i32, Error<E>> for RuntimeValue where E: CustomUserError {
fn try_into(self) -> Result<i32, Error<E>> {
match self {
RuntimeValue::I32(val) => Ok(val),
_ => Err(Error::Value(format!("32-bit int value expected"))),
@@ -196,8 +196,8 @@ impl TryInto<i32, Error> for RuntimeValue {
}
}
impl TryInto<i64, Error> for RuntimeValue {
fn try_into(self) -> Result<i64, Error> {
impl<E> TryInto<i64, Error<E>> for RuntimeValue where E: CustomUserError {
fn try_into(self) -> Result<i64, Error<E>> {
match self {
RuntimeValue::I64(val) => Ok(val),
_ => Err(Error::Value(format!("64-bit int value expected"))),
@@ -205,8 +205,8 @@ impl TryInto<i64, Error> for RuntimeValue {
}
}
impl TryInto<f32, Error> for RuntimeValue {
fn try_into(self) -> Result<f32, Error> {
impl<E> TryInto<f32, Error<E>> for RuntimeValue where E: CustomUserError {
fn try_into(self) -> Result<f32, Error<E>> {
match self {
RuntimeValue::F32(val) => Ok(val),
_ => Err(Error::Value(format!("32-bit float value expected"))),
@@ -214,8 +214,8 @@ impl TryInto<f32, Error> for RuntimeValue {
}
}
impl TryInto<f64, Error> for RuntimeValue {
fn try_into(self) -> Result<f64, Error> {
impl<E> TryInto<f64, Error<E>> for RuntimeValue where E: CustomUserError {
fn try_into(self) -> Result<f64, Error<E>> {
match self {
RuntimeValue::F64(val) => Ok(val),
_ => Err(Error::Value(format!("64-bit float value expected"))),
@@ -223,8 +223,8 @@ impl TryInto<f64, Error> for RuntimeValue {
}
}
impl TryInto<u32, Error> for RuntimeValue {
fn try_into(self) -> Result<u32, Error> {
impl<E> TryInto<u32, Error<E>> for RuntimeValue where E: CustomUserError {
fn try_into(self) -> Result<u32, Error<E>> {
match self {
RuntimeValue::I32(val) => Ok(val as u32),
_ => Err(Error::Value(format!("32-bit int value expected"))),
@@ -232,8 +232,8 @@ impl TryInto<u32, Error> for RuntimeValue {
}
}
impl TryInto<u64, Error> for RuntimeValue {
fn try_into(self) -> Result<u64, Error> {
impl<E> TryInto<u64, Error<E>> for RuntimeValue where E: CustomUserError {
fn try_into(self) -> Result<u64, Error<E>> {
match self {
RuntimeValue::I64(val) => Ok(val as u64),
_ => Err(Error::Value(format!("64-bit int value expected"))),
@@ -265,8 +265,8 @@ impl_wrap_into!(f64, f32);
macro_rules! impl_try_truncate_into {
($from: ident, $into: ident) => {
impl TryTruncateInto<$into, Error> for $from {
fn try_truncate_into(self) -> Result<$into, Error> {
impl<E> TryTruncateInto<$into, Error<E>> for $from where E: CustomUserError {
fn try_truncate_into(self) -> Result<$into, Error<E>> {
// Casting from a float to an integer will round the float towards zero
// NOTE: currently this will cause Undefined Behavior if the rounded value cannot be represented by the
// target integer type. This includes Inf and NaN. This is a bug and will be fixed.
@@ -373,31 +373,31 @@ impl TransmuteInto<f64> for i64 {
fn transmute_into(self) -> f64 { f64_from_bits(self as _) }
}
impl LittleEndianConvert for i8 {
impl<E> LittleEndianConvert<E> for i8 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
vec![self as u8]
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
buffer.get(0)
.map(|v| *v as i8)
.ok_or(Error::Value("invalid little endian buffer".into()))
}
}
impl LittleEndianConvert for u8 {
impl<E> LittleEndianConvert<E> for u8 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
vec![self]
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
buffer.get(0)
.cloned()
.ok_or(Error::Value("invalid little endian buffer".into()))
}
}
impl LittleEndianConvert for i16 {
impl<E> LittleEndianConvert<E> for i16 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
let mut vec = Vec::with_capacity(2);
vec.write_i16::<LittleEndian>(self)
@@ -405,13 +405,13 @@ impl LittleEndianConvert for i16 {
vec
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
io::Cursor::new(buffer).read_i16::<LittleEndian>()
.map_err(|e| Error::Value(e.to_string()))
}
}
impl LittleEndianConvert for u16 {
impl<E> LittleEndianConvert<E> for u16 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
let mut vec = Vec::with_capacity(2);
vec.write_u16::<LittleEndian>(self)
@@ -419,13 +419,13 @@ impl LittleEndianConvert for u16 {
vec
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
io::Cursor::new(buffer).read_u16::<LittleEndian>()
.map_err(|e| Error::Value(e.to_string()))
}
}
impl LittleEndianConvert for i32 {
impl<E> LittleEndianConvert<E> for i32 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
let mut vec = Vec::with_capacity(4);
vec.write_i32::<LittleEndian>(self)
@@ -433,13 +433,13 @@ impl LittleEndianConvert for i32 {
vec
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
io::Cursor::new(buffer).read_i32::<LittleEndian>()
.map_err(|e| Error::Value(e.to_string()))
}
}
impl LittleEndianConvert for u32 {
impl<E> LittleEndianConvert<E> for u32 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
let mut vec = Vec::with_capacity(4);
vec.write_u32::<LittleEndian>(self)
@@ -447,13 +447,13 @@ impl LittleEndianConvert for u32 {
vec
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
io::Cursor::new(buffer).read_u32::<LittleEndian>()
.map_err(|e| Error::Value(e.to_string()))
}
}
impl LittleEndianConvert for i64 {
impl<E> LittleEndianConvert<E> for i64 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
let mut vec = Vec::with_capacity(8);
vec.write_i64::<LittleEndian>(self)
@@ -461,13 +461,13 @@ impl LittleEndianConvert for i64 {
vec
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
io::Cursor::new(buffer).read_i64::<LittleEndian>()
.map_err(|e| Error::Value(e.to_string()))
}
}
impl LittleEndianConvert for f32 {
impl<E> LittleEndianConvert<E> for f32 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
let mut vec = Vec::with_capacity(4);
vec.write_f32::<LittleEndian>(self)
@@ -475,14 +475,14 @@ impl LittleEndianConvert for f32 {
vec
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
io::Cursor::new(buffer).read_u32::<LittleEndian>()
.map(f32_from_bits)
.map_err(|e| Error::Value(e.to_string()))
}
}
impl LittleEndianConvert for f64 {
impl<E> LittleEndianConvert<E> for f64 where E: CustomUserError {
fn into_little_endian(self) -> Vec<u8> {
let mut vec = Vec::with_capacity(8);
vec.write_f64::<LittleEndian>(self)
@@ -490,7 +490,7 @@ impl LittleEndianConvert for f64 {
vec
}
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error<E>> {
io::Cursor::new(buffer).read_u64::<LittleEndian>()
.map(f64_from_bits)
.map_err(|e| Error::Value(e.to_string()))
@@ -535,11 +535,11 @@ fn f64_from_bits(mut v: u64) -> f64 {
macro_rules! impl_integer_arithmetic_ops {
($type: ident) => {
impl ArithmeticOps<$type> for $type {
impl<E> ArithmeticOps<$type, E> for $type where E: CustomUserError {
fn add(self, other: $type) -> $type { self.wrapping_add(other) }
fn sub(self, other: $type) -> $type { self.wrapping_sub(other) }
fn mul(self, other: $type) -> $type { self.wrapping_mul(other) }
fn div(self, other: $type) -> Result<$type, Error> {
fn div(self, other: $type) -> Result<$type, Error<E>> {
if other == 0 { Err(Error::Value("Division by zero".to_owned())) }
else {
let (result, overflow) = self.overflowing_div(other);
@@ -561,11 +561,11 @@ impl_integer_arithmetic_ops!(u64);
macro_rules! impl_float_arithmetic_ops {
($type: ident) => {
impl ArithmeticOps<$type> for $type {
impl<E> ArithmeticOps<$type, E> for $type where E: CustomUserError {
fn add(self, other: $type) -> $type { self + other }
fn sub(self, other: $type) -> $type { self - other }
fn mul(self, other: $type) -> $type { self * other }
fn div(self, other: $type) -> Result<$type, Error> { Ok(self / other) }
fn div(self, other: $type) -> Result<$type, Error<E>> { Ok(self / other) }
}
}
}
@@ -575,13 +575,13 @@ impl_float_arithmetic_ops!(f64);
macro_rules! impl_integer {
($type: ident) => {
impl Integer<$type> for $type {
impl<E> Integer<$type, E> for $type where E: CustomUserError {
fn leading_zeros(self) -> $type { self.leading_zeros() as $type }
fn trailing_zeros(self) -> $type { self.trailing_zeros() as $type }
fn count_ones(self) -> $type { self.count_ones() as $type }
fn rotl(self, other: $type) -> $type { self.rotate_left(other as u32) }
fn rotr(self, other: $type) -> $type { self.rotate_right(other as u32) }
fn rem(self, other: $type) -> Result<$type, Error> {
fn rem(self, other: $type) -> Result<$type, Error<E>> {
if other == 0 { Err(Error::Value("Division by zero".to_owned())) }
else { Ok(self.wrapping_rem(other)) }
}
@@ -596,7 +596,7 @@ impl_integer!(u64);
macro_rules! impl_float {
($type: ident, $int_type: ident) => {
impl Float<$type> for $type {
impl<E> Float<$type, E> for $type where E: CustomUserError {
fn abs(self) -> $type { self.abs() }
fn floor(self) -> $type { self.floor() }
fn ceil(self) -> $type { self.ceil() }