Beginnings of Rust implementation

This commit is contained in:
Tony Garnock-Jones 2019-06-29 23:02:27 +01:00
parent 4d4cd6f417
commit 6960046263
5 changed files with 150 additions and 0 deletions

View File

@ -0,0 +1,10 @@
[package]
name = "preserves"
version = "0.1.0"
authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
edition = "2018"
[dependencies]
num = "0.2"
serde = "1.0"
serde_bytes = "0.11"

View File

@ -0,0 +1,2 @@
inotifytest:
inotifytest sh -c 'reset; cargo build && RUST_BACKTRACE=1 cargo test -- --nocapture'

View File

@ -0,0 +1,9 @@
pub mod value;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}

View File

@ -0,0 +1 @@
pub mod value;

View File

@ -0,0 +1,128 @@
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<u8>),
Symbol(std::string::String),
Record(std::rc::Rc<Value>, std::vec::Vec<Value>),
Sequence(std::vec::Vec<Value>),
Set(std::collections::BTreeSet<Value>),
Dictionary(std::collections::BTreeMap<Value, Value>),
}
#[derive(Clone, Debug)]
pub struct Float(f32);
#[derive(Clone, Debug)]
pub struct Double(f64);
impl From<f32> for Float {
fn from(v: f32) -> Self {
Float(v)
}
}
impl From<Float> for f32 {
fn from(v: Float) -> Self {
v.0
}
}
impl Hash for Float {
fn hash<H: Hasher>(&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<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for Float {}
impl From<f64> for Double {
fn from(v: f64) -> Self {
Double(v)
}
}
impl From<Double> for f64 {
fn from(v: Double) -> Self {
v.0
}
}
impl Hash for Double {
fn hash<H: Hasher>(&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<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for Double {}
impl From<bool> for Value { fn from(v: bool) -> Self { Value::Boolean(v) } }
impl From<f32> for Value { fn from(v: f32) -> Self { Value::Float(Float::from(v)) } }
impl From<f64> for Value { fn from(v: f64) -> Self { Value::Double(Double::from(v)) } }
impl From<u8> for Value { fn from(v: u8) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<i8> for Value { fn from(v: i8) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<u16> for Value { fn from(v: u16) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<i16> for Value { fn from(v: i16) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<u32> for Value { fn from(v: u32) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<i32> for Value { fn from(v: i32) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<u64> for Value { fn from(v: u64) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<i64> for Value { fn from(v: i64) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<u128> for Value { fn from(v: u128) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<i128> for Value { fn from(v: i128) -> Self { Value::SignedInteger(BigInt::from(v)) } }
impl From<BigInt> 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<String> for Value { fn from(v: String) -> Self { Value::String(v) } }