From 8192a5574e45ba8b1f2d5950a28c6a58491ae116 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 10 Jul 2025 03:21:56 -0700 Subject: Starting the rust version of gats. --- rust/src/lib.rs | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 rust/src/lib.rs (limited to 'rust/src') diff --git a/rust/src/lib.rs b/rust/src/lib.rs new file mode 100644 index 0000000..9b177a1 --- /dev/null +++ b/rust/src/lib.rs @@ -0,0 +1,131 @@ +use std::collections::HashMap; +use std::vec::Vec; +use std::io::{Write,Read}; +use std::num::FpCategory; + +pub enum Value { + Integer(i64), + ByteString(Vec), + Boolean(bool), + List(Vec), + Dictionary(HashMap), + Float(f64), + Nothing, +} + +// const FLOAT_DIVISOR: f64 = (256_f64).ln(); + +fn write_packed_int( x: i64 ) -> Vec +{ + let mut w = Vec::::with_capacity(10); + let mut v = x; + let mut bb = if x < 0 { + v = -v; + 0x40_u8 + } else { + 0x00_u8 + } | if v > (v & 0x3F) { 0x80_u8 } else { 0x00_u8 }; + w.push(bb); + v = v >> 6; + while v > 0 { + bb = (v & 0x7F) as u8 | if v > (v & 0x7F) { 0x80_u8 } else { 0x00_u8 }; + w.push(bb); + v = v >> 7; + } + + w +} + +fn read_packed_int( r: &mut R ) -> Result { + let mut out : i64; + let mut bb = [0u8]; + r.read( &mut bb )?; + let negative = (bb[0]&0x40_u8) == 0x40_u8; + out = (bb[0]&0x3F_u8) as i64; + let mut c = 0; + while (bb[0]&0x80_u8) != 0 { + r.read( &mut bb )?; + out |= ((bb[0]&0x7F_u8) as i64) << (6+7*c); + c += 1; + } + + if negative { + Ok(-out) + } else { + Ok(out) + } +} + +impl Value { + pub fn write(&self, w: &mut W) -> Result<(), std::io::Error> { + match self { + Self::Integer(x) => { + let mut bb = [0u8]; + bb[0] = 'i' as u8; + w.write_all(&bb)?; + w.write_all(&write_packed_int( *x ))?; + }, + Self::ByteString(s) => { + let mut bb = [0u8]; + bb[0] = 's' as u8; + w.write_all(&bb)?; + w.write_all(&write_packed_int( s.len() as i64 ))?; + w.write_all( &s )?; + }, + Self::Boolean(b) => { + let mut bb = [0u8]; + bb[0] = if *b { '1' } else { '0' } as u8; + w.write_all( &bb )?; + }, + Self::List(l) => { + }, + Self::Dictionary(d) => { + }, + Self::Float(f) => { + let mut bb = ['F' as u8, 0u8]; + match f.classify() { + FpCategory::Nan => { + bb[1] = if f.is_sign_negative() { 'N' } else { 'n' } as u8; + w.write_all( &bb )?; + }, + FpCategory::Infinite => { + bb[1] = if f.is_sign_negative() { 'I' } else { 'i' } as u8; + w.write_all( &bb )?; + }, + FpCategory::Zero => { + bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; + w.write_all( &bb )?; + }, + FpCategory::Subnormal => { + // The format doesn't account for these...uh...make them zero? + bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; + w.write_all( &bb )?; + }, + FpCategory::Normal => { + let div = 256f64.ln(); + todo!(); + + }, + } + }, + Self::Nothing => { + }, + } + Ok(()) + } +} + +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} -- cgit v1.2.3