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/.gitignore | 1 + rust/Cargo.lock | 7 +++ rust/Cargo.toml | 6 +++ rust/src/lib.rs | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 rust/.gitignore create mode 100644 rust/Cargo.lock create mode 100644 rust/Cargo.toml create mode 100644 rust/src/lib.rs diff --git a/rust/.gitignore b/rust/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/rust/.gitignore @@ -0,0 +1 @@ +/target diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 0000000..013989c --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "gats" +version = "0.1.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..d8b03fe --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gats" +version = "0.1.0" +edition = "2024" + +[dependencies] 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