use std::hash::{Hash,Hasher}; use std::cmp::{Ordering}; use num::bigint::BigInt; #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum Value { Boolean(bool), Float(Float), Double(Double), SignedInteger(BigInt), String(std::string::String), ByteString(std::vec::Vec), Symbol(std::string::String), Record(std::rc::Rc, std::vec::Vec), Sequence(std::vec::Vec), Set(std::collections::BTreeSet), Dictionary(std::collections::BTreeMap), } #[derive(Clone, Debug)] pub struct Float(f32); #[derive(Clone, Debug)] pub struct Double(f64); impl From for Float { fn from(v: f32) -> Self { Float(v) } } impl From for f32 { fn from(v: Float) -> Self { v.0 } } impl Hash for Float { fn hash(&self, state: &mut H) { self.0.to_bits().hash(state); } } impl PartialEq for Float { fn eq(&self, other: &Self) -> bool { self.0.to_bits() == other.0.to_bits() } } impl Ord for Float { fn cmp(&self, other: &Self) -> Ordering { let mut a = self.0.to_bits(); let mut b = other.0.to_bits(); if a & 0x80000000 != 0 { a ^= 0x7fffffff; } if b & 0x80000000 != 0 { b ^= 0x7fffffff; } a.cmp(&b) } } impl PartialOrd for Float { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Eq for Float {} impl From for Double { fn from(v: f64) -> Self { Double(v) } } impl From for f64 { fn from(v: Double) -> Self { v.0 } } impl Hash for Double { fn hash(&self, state: &mut H) { self.0.to_bits().hash(state); } } impl PartialEq for Double { fn eq(&self, other: &Self) -> bool { return self.0.to_bits() == other.0.to_bits(); } } impl Ord for Double { fn cmp(&self, other: &Self) -> Ordering { let mut a = self.0.to_bits(); let mut b = other.0.to_bits(); if a & 0x8000000000000000 != 0 { a ^= 0x7fffffffffffffff; } if b & 0x8000000000000000 != 0 { b ^= 0x7fffffffffffffff; } a.cmp(&b) } } impl PartialOrd for Double { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Eq for Double {} impl From for Value { fn from(v: bool) -> Self { Value::Boolean(v) } } impl From for Value { fn from(v: f32) -> Self { Value::Float(Float::from(v)) } } impl From for Value { fn from(v: f64) -> Self { Value::Double(Double::from(v)) } } impl From for Value { fn from(v: u8) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: i8) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: u16) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: i16) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: u32) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: i32) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: u64) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: i64) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: u128) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: i128) -> Self { Value::SignedInteger(BigInt::from(v)) } } impl From for Value { fn from(v: BigInt) -> Self { Value::SignedInteger(v) } } impl From<&str> for Value { fn from(v: &str) -> Self { Value::String(String::from(v)) } } impl From for Value { fn from(v: String) -> Self { Value::String(v) } }