aboutsummaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2025-11-19 13:32:09 -0800
committerMike Buland <mike@xagasoft.com>2025-11-19 13:32:09 -0800
commit61d7cdcc9ae82020f61d5c9ac1e8a2123ed7b9ac (patch)
tree86e79f2b40e75cca2b5623d9d74357b3001803ee /rust
parenta9c4c9c2cbf70686d5f21f6bd1dd5c477f4a5085 (diff)
downloadlibgats-61d7cdcc9ae82020f61d5c9ac1e8a2123ed7b9ac.tar.gz
libgats-61d7cdcc9ae82020f61d5c9ac1e8a2123ed7b9ac.tar.bz2
libgats-61d7cdcc9ae82020f61d5c9ac1e8a2123ed7b9ac.tar.xz
libgats-61d7cdcc9ae82020f61d5c9ac1e8a2123ed7b9ac.zip
read/write all work.
Diffstat (limited to '')
-rw-r--r--rust/src/lib.rs137
1 files changed, 92 insertions, 45 deletions
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 300fa99..5a5f96a 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -1,9 +1,8 @@
1use std::collections::HashMap; 1use std::collections::HashMap;
2use std::vec::Vec; 2use std::vec::Vec;
3use std::io::{Write,Read}; 3use std::io::{Write,Read,Cursor,Error,ErrorKind};
4use std::num::FpCategory; 4use std::num::FpCategory;
5use std::sync::LazyLock; 5use std::sync::LazyLock;
6use std::io::Cursor;
7 6
8#[derive(PartialEq)] 7#[derive(PartialEq)]
9pub enum Value { 8pub enum Value {
@@ -16,7 +15,12 @@ pub enum Value {
16 Nothing, 15 Nothing,
17} 16}
18 17
19pub enum ValueParse { 18pub enum BytesToRead {
19 Estimate(usize),
20 Final(usize),
21}
22
23enum ValueParse {
20 Value(Value), 24 Value(Value),
21 EndMarker, 25 EndMarker,
22} 26}
@@ -77,7 +81,7 @@ fn write_packed_int( x: i64 ) -> Vec<u8>
77 w 81 w
78} 82}
79 83
80fn read_packed_int<R: Read>( r: &mut R ) -> Result<i64, std::io::Error> { 84fn read_packed_int<R: Read>( r: &mut R ) -> Result<i64, Error> {
81 let mut out : i64; 85 let mut out : i64;
82 let mut bb = [0u8]; 86 let mut bb = [0u8];
83 r.read( &mut bb )?; 87 r.read( &mut bb )?;
@@ -98,7 +102,7 @@ fn read_packed_int<R: Read>( r: &mut R ) -> Result<i64, std::io::Error> {
98} 102}
99 103
100impl Value { 104impl Value {
101 pub fn write<W: Write>(&self, w: &mut W) -> Result<(), std::io::Error> { 105 pub fn write<W: Write>(&self, w: &mut W) -> Result<(), Error> {
102 match self { 106 match self {
103 Self::Integer(x) => { 107 Self::Integer(x) => {
104 let bb = ['i' as u8]; 108 let bb = ['i' as u8];
@@ -194,7 +198,7 @@ impl Value {
194 Ok(()) 198 Ok(())
195 } 199 }
196 200
197 fn read_parse<R: Read>(r: &mut R) -> Result<ValueParse, std::io::Error> { 201 fn read_parse<R: Read>(r: &mut R) -> Result<ValueParse, Error> {
198 let it = { 202 let it = {
199 let mut it = [0u8]; 203 let mut it = [0u8];
200 r.read_exact( &mut it )?; 204 r.read_exact( &mut it )?;
@@ -260,7 +264,7 @@ impl Value {
260 'Z' => Ok(ValueParse::Value(Value::Float(-0.0f64))), 264 'Z' => Ok(ValueParse::Value(Value::Float(-0.0f64))),
261 'z' => Ok(ValueParse::Value(Value::Float(0.0f64))), 265 'z' => Ok(ValueParse::Value(Value::Float(0.0f64))),
262 _ => { 266 _ => {
263 return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Unknown exceptional float subtype found.")); 267 return Err(Error::new(ErrorKind::InvalidData, "Unknown exceptional float subtype found."));
264 } 268 }
265 } 269 }
266 } 270 }
@@ -273,10 +277,10 @@ impl Value {
273 if let Ok(s) = String::from_utf8(s) { 277 if let Ok(s) = String::from_utf8(s) {
274 s 278 s
275 } else { 279 } else {
276 return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Keys must be utf8 compatbile strings.")); 280 return Err(Error::new(ErrorKind::InvalidData, "Keys must be utf8 compatbile strings."));
277 } 281 }
278 } else { 282 } else {
279 return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Non-string cannot be dictionary key.")); 283 return Err(Error::new(ErrorKind::InvalidData, "Non-string cannot be dictionary key."));
280 } 284 }
281 }, 285 },
282 ValueParse::EndMarker => break, 286 ValueParse::EndMarker => break,
@@ -284,7 +288,7 @@ impl Value {
284 let v = match Value::read_parse(r)? { 288 let v = match Value::read_parse(r)? {
285 ValueParse::Value(v) => v, 289 ValueParse::Value(v) => v,
286 ValueParse::EndMarker => { 290 ValueParse::EndMarker => {
287 return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Premature end marker in dictionary.")); 291 return Err(Error::new(ErrorKind::InvalidData, "Premature end marker in dictionary."));
288 } 292 }
289 }; 293 };
290 body.insert( k, v ); 294 body.insert( k, v );
@@ -292,20 +296,20 @@ impl Value {
292 Ok(ValueParse::Value(Value::Dictionary(body))) 296 Ok(ValueParse::Value(Value::Dictionary(body)))
293 } 297 }
294 _ => { 298 _ => {
295 Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid data type specified.")) 299 Err(Error::new(ErrorKind::InvalidData, "Invalid data type specified."))
296 } 300 }
297 } 301 }
298 } 302 }
299 303
300 pub fn read<R: Read>(r: &mut R) -> Result<Value, std::io::Error> { 304 pub fn read<R: Read>(r: &mut R) -> Result<Value, Error> {
301 match Value::read_parse(r) { 305 match Value::read_parse(r) {
302 Ok(ValueParse::Value(v)) => Ok(v), 306 Ok(ValueParse::Value(v)) => Ok(v),
303 Ok(ValueParse::EndMarker) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Unexpecetd EndMarker while parsing structure.")), 307 Ok(ValueParse::EndMarker) => Err(Error::new(ErrorKind::InvalidData, "Unexpecetd EndMarker while parsing structure.")),
304 Err(e) => Err(e) 308 Err(e) => Err(e)
305 } 309 }
306 } 310 }
307 311
308 pub fn to_packet( &self ) -> Result<Vec<u8>, std::io::Error> { 312 pub fn to_packet( &self ) -> Result<Vec<u8>, Error> {
309 let mut body : Vec<u8> = vec![1u8,0u8,0u8,0u8,0u8]; 313 let mut body : Vec<u8> = vec![1u8,0u8,0u8,0u8,0u8];
310 self.write( &mut body )?; 314 self.write( &mut body )?;
311 let len = body.len() as u32; 315 let len = body.len() as u32;
@@ -313,7 +317,7 @@ impl Value {
313 Ok(body) 317 Ok(body)
314 } 318 }
315 319
316 pub fn write_packet<W: Write>( &self, w: &mut W ) -> Result<(), std::io::Error> { 320 pub fn write_packet<W: Write>( &self, w: &mut W ) -> Result<(), Error> {
317 match self.to_packet() { 321 match self.to_packet() {
318 Ok(body) => { 322 Ok(body) => {
319 w.write_all( &body ) 323 w.write_all( &body )
@@ -324,18 +328,60 @@ impl Value {
324 } 328 }
325 } 329 }
326 330
327 pub fn from_packet<R: Read>( r: &mut R ) -> Result<Value, std::io::Error> { 331 pub fn bytes_to_read( r: &[u8] ) -> Result<BytesToRead, Error> {
328 let mut ver = [0u8]; 332 if r.len() < 5 {
329 let mut size = [0u8; 4]; 333 Ok(BytesToRead::Estimate(5))
330 r.read_exact( &mut ver )?; 334 } else {
331 if ver[0] != 1 { 335 if r[0] != 1 {
332 return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid gats packet version.")); 336 return Err(Error::new(ErrorKind::InvalidData, "Invalid gats packet version."));
337 }
338 if let Ok(ar) = r[1..5].try_into() {
339 Ok(BytesToRead::Final(i32::from_be_bytes( ar ) as usize))
340 } else {
341 Err(Error::new(ErrorKind::UnexpectedEof, "Insufficient data presented to decode packet header."))
342 }
343 }
344 }
345
346 pub fn from_packet( r: &[u8] ) -> Result<Value, Error> {
347 if r.len() < 5 {
348 return Err(Error::new(ErrorKind::UnexpectedEof, "Insufficient data presented to decode packet header."));
349 }
350 if r[0] != 1 {
351 return Err(Error::new(ErrorKind::InvalidData, "Invalid gats packet version."));
352 }
353 let size = if let Ok(ar) = r[1..5].try_into() {
354 i32::from_be_bytes( ar )
355 } else {
356 return Err(Error::new(ErrorKind::UnexpectedEof, "Insufficient data presented to decode packet header."));
357 };
358 if r.len() != size as usize {
359 return Err(Error::new(ErrorKind::InvalidData, "Packet buffer is the wrong length."));
360 }
361 Ok(Value::read( &mut Cursor::new( &r[5..] ) )?)
362 }
363
364 pub fn read_packet<R: Read>( r: &mut R ) -> Result<Value,Error> {
365 let mut buf = Vec::<u8>::new();
366 let mut fill = 0usize;
367 loop {
368 match Value::bytes_to_read( &buf ) {
369 Ok(BytesToRead::Estimate(size)) => {
370 buf.resize(size, 0u8);
371 r.read_exact( &mut buf[fill..] )?;
372 fill = buf.len();
373 }
374 Ok(BytesToRead::Final(size)) => {
375 buf.resize(size, 0u8);
376 r.read_exact( &mut buf[fill..] )?;
377 //fill = buf.len();
378 return Value::from_packet( &buf );
379 }
380 Err(e) => {
381 return Err(e);
382 }
383 }
333 } 384 }
334 r.read_exact( &mut size )?;
335 let size = i32::from_be_bytes( size );
336 let mut buf = vec![0u8; size as usize -5];
337 r.read_exact( &mut buf )?;
338 Ok(Value::read( &mut Cursor::new( buf ) )?)
339 } 385 }
340} 386}
341 387
@@ -347,25 +393,6 @@ mod tests {
347 use std::io::Cursor; 393 use std::io::Cursor;
348 394
349 #[test] 395 #[test]
350 fn write_file1() -> Result<(),Box<dyn Error>> {
351 let mut f = File::create("test.gats")?;
352 let v = Value::Dictionary(HashMap::from([
353 ("biggerint".to_string(), Value::Integer(98765)),
354 ("negint".to_string(), Value::Integer(-98765)),
355 ("integer".to_string(), Value::Integer(44)),
356 ("boolean".to_string(), Value::Boolean(true)),
357 ("list".to_string(), Value::List(vec![
358 Value::Integer(1), Value::Integer(1), Value::Integer(2),
359 Value::Integer(3), Value::Integer(5), Value::Integer(8),
360 ])),
361 ("null".to_string(), Value::Nothing),
362 ("float".to_string(), Value::Float(123.456)),
363 ]));
364 v.write_packet( &mut f )?;
365 Ok(())
366 }
367
368 #[test]
369 fn round_int() -> Result<(),Box<dyn Error>> { 396 fn round_int() -> Result<(),Box<dyn Error>> {
370 let v = Value::Integer(555666); 397 let v = Value::Integer(555666);
371 let mut buf = Vec::<u8>::new(); 398 let mut buf = Vec::<u8>::new();
@@ -469,4 +496,24 @@ mod tests {
469 assert!( v == v2 ); 496 assert!( v == v2 );
470 Ok(()) 497 Ok(())
471 } 498 }
499
500 #[test]
501 fn packet_1() -> Result<(), Box<dyn Error>> {
502 let v = Value::Dictionary(HashMap::from([
503 ("biggerint".to_string(), Value::Integer(98765)),
504 ("negint".to_string(), Value::Integer(-98765)),
505 ("integer".to_string(), Value::Integer(44)),
506 ("boolean".to_string(), Value::Boolean(true)),
507 ("list".to_string(), Value::List(vec![
508 Value::Integer(1), Value::Integer(1), Value::Integer(2),
509 Value::Integer(3), Value::Integer(5), Value::Integer(8),
510 ])),
511 ("null".to_string(), Value::Nothing),
512 ("float".to_string(), Value::Float(123.456)),
513 ]));
514 let buf = v.to_packet()?;
515 let v2 = Value::from_packet( &buf )?;
516 assert!( v == v2 );
517 Ok(())
518 }
472} 519}