diff options
Diffstat (limited to 'rust/src/lib.rs')
| -rw-r--r-- | rust/src/lib.rs | 58 |
1 files changed, 47 insertions, 11 deletions
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; | |||
| 2 | use std::vec::Vec; | 2 | use std::vec::Vec; |
| 3 | use std::io::{Write,Read}; | 3 | use std::io::{Write,Read}; |
| 4 | use std::num::FpCategory; | 4 | use std::num::FpCategory; |
| 5 | use std::sync::LazyLock; | ||
| 5 | 6 | ||
| 6 | pub enum Value { | 7 | pub enum Value { |
| 7 | Integer(i64), | 8 | Integer(i64), |
| @@ -13,7 +14,7 @@ pub enum Value { | |||
| 13 | Nothing, | 14 | Nothing, |
| 14 | } | 15 | } |
| 15 | 16 | ||
| 16 | // const FLOAT_DIVISOR: f64 = (256_f64).ln(); | 17 | static FLOAT_DIVISOR: LazyLock<f64> = LazyLock::new(|| (256_f64).ln()); |
| 17 | 18 | ||
| 18 | fn write_packed_int( x: i64 ) -> Vec<u8> | 19 | fn write_packed_int( x: i64 ) -> Vec<u8> |
| 19 | { | 20 | { |
| @@ -23,8 +24,8 @@ fn write_packed_int( x: i64 ) -> Vec<u8> | |||
| 23 | v = -v; | 24 | v = -v; |
| 24 | 0x40_u8 | 25 | 0x40_u8 |
| 25 | } else { | 26 | } else { |
| 26 | 0x00_u8 | 27 | 0x00_u8 |
| 27 | } | if v > (v & 0x3F) { 0x80_u8 } else { 0x00_u8 }; | 28 | } | (v&0x3F) as u8 | if v > (v & 0x3F) { 0x80_u8 } else { 0x00_u8 }; |
| 28 | w.push(bb); | 29 | w.push(bb); |
| 29 | v = v >> 6; | 30 | v = v >> 6; |
| 30 | while v > 0 { | 31 | while v > 0 { |
| @@ -85,31 +86,44 @@ impl Value { | |||
| 85 | w.write_all(&bb)?; | 86 | w.write_all(&bb)?; |
| 86 | }, | 87 | }, |
| 87 | Self::Dictionary(d) => { | 88 | Self::Dictionary(d) => { |
| 89 | let mut bb = ['d' as u8]; | ||
| 90 | w.write_all(&bb)?; | ||
| 91 | for (k, v) in d { | ||
| 92 | (Value::ByteString( k.clone().into_bytes() )).write( w )?; | ||
| 93 | v.write( w )?; | ||
| 94 | } | ||
| 95 | bb[0] = 'e' as u8; | ||
| 96 | w.write_all(&bb)?; | ||
| 88 | }, | 97 | }, |
| 89 | Self::Float(f) => { | 98 | Self::Float(f) => { |
| 90 | let mut bb = ['F' as u8, 0u8]; | ||
| 91 | match f.classify() { | 99 | match f.classify() { |
| 92 | FpCategory::Nan => { | 100 | FpCategory::Nan => { |
| 101 | let mut bb = ['F' as u8, 0u8]; | ||
| 93 | bb[1] = if f.is_sign_negative() { 'N' } else { 'n' } as u8; | 102 | bb[1] = if f.is_sign_negative() { 'N' } else { 'n' } as u8; |
| 94 | w.write_all( &bb )?; | 103 | w.write_all( &bb )?; |
| 95 | }, | 104 | }, |
| 96 | FpCategory::Infinite => { | 105 | FpCategory::Infinite => { |
| 106 | let mut bb = ['F' as u8, 0u8]; | ||
| 97 | bb[1] = if f.is_sign_negative() { 'I' } else { 'i' } as u8; | 107 | bb[1] = if f.is_sign_negative() { 'I' } else { 'i' } as u8; |
| 98 | w.write_all( &bb )?; | 108 | w.write_all( &bb )?; |
| 99 | }, | 109 | }, |
| 100 | FpCategory::Zero => { | 110 | FpCategory::Zero => { |
| 111 | let mut bb = ['F' as u8, 0u8]; | ||
| 101 | bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; | 112 | bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; |
| 102 | w.write_all( &bb )?; | 113 | w.write_all( &bb )?; |
| 103 | }, | 114 | }, |
| 104 | FpCategory::Subnormal => { | 115 | FpCategory::Subnormal => { |
| 116 | let mut bb = ['F' as u8, 0u8]; | ||
| 105 | // The format doesn't account for these...uh...make them zero? | 117 | // The format doesn't account for these...uh...make them zero? |
| 106 | bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; | 118 | bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; |
| 107 | w.write_all( &bb )?; | 119 | w.write_all( &bb )?; |
| 108 | }, | 120 | }, |
| 109 | FpCategory::Normal => { | 121 | FpCategory::Normal => { |
| 122 | let bb = ['f' as u8]; | ||
| 123 | w.write_all( &bb )?; | ||
| 110 | let mut bin = Vec::<u8>::with_capacity(10); | 124 | let mut bin = Vec::<u8>::with_capacity(10); |
| 111 | let (negative, d) = if f.is_sign_negative() { (true, -*f) } else { (false, *f) }; | 125 | let (negative, d) = if f.is_sign_negative() { (true, -*f) } else { (false, *f) }; |
| 112 | let scale : i64 = (d.ln() / 256.0f64.ln()) as i64; | 126 | let scale : i64 = (d.ln() / *FLOAT_DIVISOR) as i64; |
| 113 | let scale = if scale < 0 { -1 } else { scale }; | 127 | let scale = if scale < 0 { -1 } else { scale }; |
| 114 | let mut d = d / 256.0_f64.powf( scale as f64 ); | 128 | let mut d = d / 256.0_f64.powf( scale as f64 ); |
| 115 | bin.push( d as u8 ); | 129 | bin.push( d as u8 ); |
| @@ -139,19 +153,41 @@ impl Value { | |||
| 139 | } | 153 | } |
| 140 | Ok(()) | 154 | Ok(()) |
| 141 | } | 155 | } |
| 142 | } | ||
| 143 | 156 | ||
| 144 | pub fn add(left: u64, right: u64) -> u64 { | 157 | pub fn write_packet<W: Write>( &self, w: &mut W ) -> Result<(), std::io::Error> { |
| 145 | left + right | 158 | let mut body : Vec<u8> = vec![1u8,0u8,0u8,0u8,0u8]; |
| 159 | self.write( &mut body )?; | ||
| 160 | let len = body.len() as u32; | ||
| 161 | body[1..5].copy_from_slice( &len.to_be_bytes() ); | ||
| 162 | w.write_all( &body ) | ||
| 163 | } | ||
| 164 | |||
| 165 | |||
| 146 | } | 166 | } |
| 147 | 167 | ||
| 148 | #[cfg(test)] | 168 | #[cfg(test)] |
| 149 | mod tests { | 169 | mod tests { |
| 150 | use super::*; | 170 | use super::*; |
| 171 | use core::error::Error; | ||
| 172 | use std::fs::File; | ||
| 173 | use std::io::prelude::*; | ||
| 151 | 174 | ||
| 152 | #[test] | 175 | #[test] |
| 153 | fn it_works() { | 176 | fn write_file1() -> Result<(),Box<dyn Error>> { |
| 154 | let result = add(2, 2); | 177 | let mut f = File::create("test.gats")?; |
| 155 | assert_eq!(result, 4); | 178 | let v = Value::Dictionary(HashMap::from([ |
| 179 | ("biggerint".to_string(), Value::Integer(98765)), | ||
| 180 | ("negint".to_string(), Value::Integer(-98765)), | ||
| 181 | ("integer".to_string(), Value::Integer(44)), | ||
| 182 | ("boolean".to_string(), Value::Boolean(true)), | ||
| 183 | ("list".to_string(), Value::List(vec![ | ||
| 184 | Value::Integer(1), Value::Integer(1), Value::Integer(2), | ||
| 185 | Value::Integer(3), Value::Integer(5), Value::Integer(8), | ||
| 186 | ])), | ||
| 187 | ("null".to_string(), Value::Nothing), | ||
| 188 | ("float".to_string(), Value::Float(123.456)), | ||
| 189 | ])); | ||
| 190 | v.write_packet( &mut f ); | ||
| 191 | Ok(()) | ||
| 156 | } | 192 | } |
| 157 | } | 193 | } |
