From 85ab7402c54593517b4096af7dacb20e53e45a25 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 19 Nov 2025 09:15:44 -0800 Subject: All writing functions seem to be fine. --- rust/src/lib.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 11 deletions(-) (limited to 'rust') diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 1508594..88b999d 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::vec::Vec; use std::io::{Write,Read}; use std::num::FpCategory; +use std::sync::LazyLock; pub enum Value { Integer(i64), @@ -13,7 +14,7 @@ pub enum Value { Nothing, } -// const FLOAT_DIVISOR: f64 = (256_f64).ln(); +static FLOAT_DIVISOR: LazyLock = LazyLock::new(|| (256_f64).ln()); fn write_packed_int( x: i64 ) -> Vec { @@ -23,8 +24,8 @@ fn write_packed_int( x: i64 ) -> Vec v = -v; 0x40_u8 } else { - 0x00_u8 - } | if v > (v & 0x3F) { 0x80_u8 } else { 0x00_u8 }; + 0x00_u8 + } | (v&0x3F) as u8 | if v > (v & 0x3F) { 0x80_u8 } else { 0x00_u8 }; w.push(bb); v = v >> 6; while v > 0 { @@ -85,31 +86,44 @@ impl Value { w.write_all(&bb)?; }, Self::Dictionary(d) => { + let mut bb = ['d' as u8]; + w.write_all(&bb)?; + for (k, v) in d { + (Value::ByteString( k.clone().into_bytes() )).write( w )?; + v.write( w )?; + } + bb[0] = 'e' as u8; + w.write_all(&bb)?; }, Self::Float(f) => { - let mut bb = ['F' as u8, 0u8]; match f.classify() { FpCategory::Nan => { + let mut bb = ['F' as u8, 0u8]; bb[1] = if f.is_sign_negative() { 'N' } else { 'n' } as u8; w.write_all( &bb )?; }, FpCategory::Infinite => { + let mut bb = ['F' as u8, 0u8]; bb[1] = if f.is_sign_negative() { 'I' } else { 'i' } as u8; w.write_all( &bb )?; }, FpCategory::Zero => { + let mut bb = ['F' as u8, 0u8]; bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; w.write_all( &bb )?; }, FpCategory::Subnormal => { + let mut bb = ['F' as u8, 0u8]; // 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 bb = ['f' as u8]; + w.write_all( &bb )?; let mut bin = Vec::::with_capacity(10); let (negative, d) = if f.is_sign_negative() { (true, -*f) } else { (false, *f) }; - let scale : i64 = (d.ln() / 256.0f64.ln()) as i64; + let scale : i64 = (d.ln() / *FLOAT_DIVISOR) as i64; let scale = if scale < 0 { -1 } else { scale }; let mut d = d / 256.0_f64.powf( scale as f64 ); bin.push( d as u8 ); @@ -139,19 +153,41 @@ impl Value { } Ok(()) } -} -pub fn add(left: u64, right: u64) -> u64 { - left + right + pub fn write_packet( &self, w: &mut W ) -> Result<(), std::io::Error> { + let mut body : Vec = vec![1u8,0u8,0u8,0u8,0u8]; + self.write( &mut body )?; + let len = body.len() as u32; + body[1..5].copy_from_slice( &len.to_be_bytes() ); + w.write_all( &body ) + } + + } #[cfg(test)] mod tests { use super::*; + use core::error::Error; + use std::fs::File; + use std::io::prelude::*; #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); + fn write_file1() -> Result<(),Box> { + let mut f = File::create("test.gats")?; + let v = Value::Dictionary(HashMap::from([ + ("biggerint".to_string(), Value::Integer(98765)), + ("negint".to_string(), Value::Integer(-98765)), + ("integer".to_string(), Value::Integer(44)), + ("boolean".to_string(), Value::Boolean(true)), + ("list".to_string(), Value::List(vec![ + Value::Integer(1), Value::Integer(1), Value::Integer(2), + Value::Integer(3), Value::Integer(5), Value::Integer(8), + ])), + ("null".to_string(), Value::Nothing), + ("float".to_string(), Value::Float(123.456)), + ])); + v.write_packet( &mut f ); + Ok(()) } } -- cgit v1.2.3