vm_value 0.4.3

Core value trait used by fn_vm, this crate is meant to provide the building blocks to creating pass by value VMs in rust.
Documentation
use small_len::SmallLen;
use var_num::{VarFloat, VarInt, VarNum, VarUInt};
use crate::{length_to_bytes, Logical, VM, VMValue};

#[macro_export]
macro_rules! impl_logical_for_num {
    ($($t:ty),*) => {
        $(
            impl Logical for $t {
                fn bool_and(&self, b: &Self) -> bool {
                    self.is_zero() && b.is_zero()
                }

                fn bool_or(&self, b: &Self) -> bool {
                    self.is_zero() || b.is_zero()
                }

                fn bool_xor(&self, b: &Self) -> bool {
                    self.is_zero() ^ b.is_zero()
                }

                fn bool_not(&self) -> bool {
                    self.is_non_zero()
                }

                fn bitwise_reverse(&self) -> Self {
                    self.reverse()
                }
            }
        )*
    }
}

impl_logical_for_num!(VarUInt, VarInt, VarFloat, VarNum);

macro_rules! impl_vm_value_for_num {
    ($($t:ty),*) => {
        $(
            impl <Op, Val> VMValue<Op, Val, $t> for $t {
                fn create_from_vm_bytes<V: VM<Op, Val, $t>>(vm: &mut V) -> $t {
                    let len = vm.next_len();
                    let bytes = vm.next_n_bytes_vec(len);
                    <$t>::from_bytes(bytes)
                }

                fn to_vm_bytes(&self) -> Vec<u8> {
                    let bytes = self.to_bytes();
                    let mut r = length_to_bytes(&bytes.small_len());
                    r.extend(bytes);
                    r
                }
            }
        )*
    }
}

impl_vm_value_for_num!(VarUInt, VarInt, VarFloat);

impl <Op, Val> VMValue<Op, Val, VarNum> for VarNum {
    fn create_from_vm_bytes<V: VM<Op, Val, VarNum>>(vm: &mut V) -> VarNum {
        let byte = vm.next_byte();
        let len = vm.next_len();
        let bytes = vm.next_n_bytes_vec(len);
        match byte {
            0 => VarNum::Int(VarInt::from_bytes(bytes)),
            1 => VarNum::UInt(VarUInt::from_bytes(bytes)),
            2 => VarNum::Float(VarFloat::from_bytes(bytes)),
            b => panic!("Unsupported byte: {}", b)
        }
    }

    fn to_vm_bytes(&self) -> Vec<u8> {
        let mut r = vec![];
        match self {
            VarNum::Int(i) => {
                r.push(0);
                r.extend(i.to_bytes());
            }
            VarNum::UInt(u) => {
                r.push(1);
                r.extend(u.to_bytes());
            }
            VarNum::Float(f) => {
                r.push(2);
                r.extend(f.to_bytes());
            }
        }
        r
    }
}