Beginnings of Rust implementation
This commit is contained in:
parent
4d4cd6f417
commit
6960046263
|
@ -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"
|
|
@ -0,0 +1,2 @@
|
|||
inotifytest:
|
||||
inotifytest sh -c 'reset; cargo build && RUST_BACKTRACE=1 cargo test -- --nocapture'
|
|
@ -0,0 +1,9 @@
|
|||
pub mod value;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod value;
|
|
@ -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) } }
|
Loading…
Reference in New Issue