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