aboutsummaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2025-11-19 14:25:48 -0800
committerMike Buland <mike@xagasoft.com>2025-11-19 14:25:48 -0800
commit8c5b9963e3467434777eeb104111478e39190384 (patch)
treeb73e131e8d0cb381babb2c871c487df084875d4b /rust/src
parent0193a1fb63c0cefcb352d5be50bf160cb3418cd8 (diff)
downloadlibgats-8c5b9963e3467434777eeb104111478e39190384.tar.gz
libgats-8c5b9963e3467434777eeb104111478e39190384.tar.bz2
libgats-8c5b9963e3467434777eeb104111478e39190384.tar.xz
libgats-8c5b9963e3467434777eeb104111478e39190384.zip
Added a bunch of docs, helpers and test functions.
Also formatted.
Diffstat (limited to '')
-rw-r--r--rust/src/lib.rs479
1 files changed, 311 insertions, 168 deletions
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 88d3410..2ccc2cf 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -1,9 +1,34 @@
1//! GATS - Generalized Agile Transport System
2//!
3//! This is a format designed to pack complex data structures into compact and
4//! easily transmissible packets that are platform independent. This format
5//! supports integers, byte arrays, booleans, lists, dictionaries (with string
6//! keys), floats, and null.
7//!
8//! Integers are stored in a packed format that requires only as many bytes as
9//! it takes to represent the value. This generally results in a reduction of
10//! space used, and rarely an increase.
11//!
12//! Floating point numbers are architecture independent and stored in a similar
13//! packed format to present them as accurately as possible in the minimal
14//! amount of space.
15//!
16//! In theory, both the integer and floating point formats are unbound and could
17//! represent values with any number of bytes, but in reality most
18//! implementations limit this to 64 bits.
19//!
20//! For easy transmission each Gats Value can be serialized as a packet, which
21//! contains a version header and a total size which makes it easier to read
22//! from a socket or the like. Each packet can only contain one value, but
23//! values can be complex types.
24
1use std::collections::HashMap; 25use std::collections::HashMap;
2use std::vec::Vec; 26use std::io::{Cursor, Error, ErrorKind, Read, Write};
3use std::io::{Write,Read,Cursor,Error,ErrorKind};
4use std::num::FpCategory; 27use std::num::FpCategory;
5use std::sync::LazyLock; 28use std::sync::LazyLock;
29use std::vec::Vec;
6 30
31/// Represents a value in a Gats structure.
7#[derive(PartialEq)] 32#[derive(PartialEq)]
8pub enum Value { 33pub enum Value {
9 Integer(i64), 34 Integer(i64),
@@ -12,14 +37,21 @@ pub enum Value {
12 List(Vec<Value>), 37 List(Vec<Value>),
13 Dictionary(HashMap<String, Value>), 38 Dictionary(HashMap<String, Value>),
14 Float(f64), 39 Float(f64),
15 Nothing, 40 Null,
16} 41}
17 42
43/// Used by the Value::bytes_to_read function to communicate with the caller
44/// about their buffer so far. If Estimate is returned then you should
45/// reallocate, read data, and try again. If final is returned then there is
46/// no reason to call the estimate any more, you can just be done once you've
47/// resized and filled the buffer.
18pub enum BytesToRead { 48pub enum BytesToRead {
19 Estimate(usize), 49 Estimate(usize),
20 Final(usize), 50 Final(usize),
21} 51}
22 52
53/// Used by the parser internally to handle values in the format that are not
54/// Values but are needed to parse the data.
23enum ValueParse { 55enum ValueParse {
24 Value(Value), 56 Value(Value),
25 EndMarker, 57 EndMarker,
@@ -55,21 +87,53 @@ impl PartialEq<bool> for Value {
55 } 87 }
56} 88}
57 89
58impl std::cmp::Eq for Value { 90impl PartialEq<Vec<Value>> for Value {
91 fn eq(&self, other: &Vec<Value>) -> bool {
92 if let Value::List(x) = self {
93 x == other
94 } else {
95 false
96 }
97 }
98}
99
100impl PartialEq<HashMap<String, Value>> for Value {
101 fn eq(&self, other: &HashMap<String, Value>) -> bool {
102 if let Value::Dictionary(x) = self {
103 x == other
104 } else {
105 false
106 }
107 }
59} 108}
60 109
110impl PartialEq<f64> for Value {
111 fn eq(&self, other: &f64) -> bool {
112 if let Value::Float(x) = self {
113 x == other
114 } else {
115 false
116 }
117 }
118}
119
120impl std::cmp::Eq for Value {}
121
122/// Used for converting floating point numbers to their packed format,
123/// this isn't a number we can store easily as a literal without a hex format.
61static FLOAT_DIVISOR: LazyLock<f64> = LazyLock::new(|| (256_f64).ln()); 124static FLOAT_DIVISOR: LazyLock<f64> = LazyLock::new(|| (256_f64).ln());
62 125
63fn write_packed_int( x: i64 ) -> Vec<u8> 126/// Internal helper to convert a number into a packed format.
64{ 127fn write_packed_int(x: i64) -> Vec<u8> {
65 let mut w = Vec::<u8>::with_capacity(10); 128 let mut w = Vec::<u8>::with_capacity(10);
66 let mut v = x; 129 let mut v = x;
67 let mut bb = if x < 0 { 130 let mut bb = if x < 0 {
68 v = -v; 131 v = -v;
69 0x40_u8 132 0x40_u8
70 } else { 133 } else {
71 0x00_u8 134 0x00_u8
72 } | (v&0x3F) as u8 | if v > (v & 0x3F) { 0x80_u8 } else { 0x00_u8 }; 135 } | (v & 0x3F) as u8
136 | if v > (v & 0x3F) { 0x80_u8 } else { 0x00_u8 };
73 w.push(bb); 137 w.push(bb);
74 v >>= 6; 138 v >>= 6;
75 while v > 0 { 139 while v > 0 {
@@ -81,119 +145,125 @@ fn write_packed_int( x: i64 ) -> Vec<u8>
81 w 145 w
82} 146}
83 147
84fn read_packed_int<R: Read>( r: &mut R ) -> Result<i64, Error> { 148/// Internal helper to convert a buffer containing a packed integer back into
85 let mut out : i64; 149/// an integer. Any extra data will be ignored.
150fn read_packed_int<R: Read>(r: &mut R) -> Result<i64, Error> {
151 let mut out: i64;
86 let mut bb = [0u8]; 152 let mut bb = [0u8];
87 r.read_exact( &mut bb )?; 153 r.read_exact(&mut bb)?;
88 let negative = (bb[0]&0x40_u8) == 0x40_u8; 154 let negative = (bb[0] & 0x40_u8) == 0x40_u8;
89 out = (bb[0]&0x3F_u8) as i64; 155 out = (bb[0] & 0x3F_u8) as i64;
90 let mut c = 0; 156 let mut c = 0;
91 while (bb[0]&0x80_u8) != 0 { 157 while (bb[0] & 0x80_u8) != 0 {
92 r.read_exact( &mut bb )?; 158 r.read_exact(&mut bb)?;
93 out |= ((bb[0]&0x7F_u8) as i64) << (6+7*c); 159 out |= ((bb[0] & 0x7F_u8) as i64) << (6 + 7 * c);
94 c += 1; 160 c += 1;
95 } 161 }
96 162
97 if negative { 163 if negative { Ok(-out) } else { Ok(out) }
98 Ok(-out)
99 } else {
100 Ok(out)
101 }
102} 164}
103 165
104impl Value { 166impl Value {
167 pub fn is_null(&self) -> bool {
168 matches!(self, Value::Null)
169 }
170
105 pub fn write<W: Write>(&self, w: &mut W) -> Result<(), Error> { 171 pub fn write<W: Write>(&self, w: &mut W) -> Result<(), Error> {
106 match self { 172 match self {
107 Self::Integer(x) => { 173 Self::Integer(x) => {
108 let bb = [b'i']; 174 let bb = [b'i'];
109 w.write_all(&bb)?; 175 w.write_all(&bb)?;
110 w.write_all(&write_packed_int( *x ))?; 176 w.write_all(&write_packed_int(*x))?;
111 }, 177 }
112 Self::ByteString(s) => { 178 Self::ByteString(s) => {
113 let bb = [b's']; 179 let bb = [b's'];
114 w.write_all(&bb)?; 180 w.write_all(&bb)?;
115 w.write_all(&write_packed_int( s.len() as i64 ))?; 181 w.write_all(&write_packed_int(s.len() as i64))?;
116 w.write_all( s )?; 182 w.write_all(s)?;
117 }, 183 }
118 Self::Boolean(b) => { 184 Self::Boolean(b) => {
119 let mut bb = [0u8]; 185 let mut bb = [0u8];
120 bb[0] = if *b { b'1' } else { b'0' }; 186 bb[0] = if *b { b'1' } else { b'0' };
121 w.write_all( &bb )?; 187 w.write_all(&bb)?;
122 }, 188 }
123 Self::List(l) => { 189 Self::List(l) => {
124 let mut bb = [b'l']; 190 let mut bb = [b'l'];
125 w.write_all(&bb)?; 191 w.write_all(&bb)?;
126 for v in l { 192 for v in l {
127 v.write( w )?; 193 v.write(w)?;
128 } 194 }
129 bb[0] = b'e'; 195 bb[0] = b'e';
130 w.write_all(&bb)?; 196 w.write_all(&bb)?;
131 }, 197 }
132 Self::Dictionary(d) => { 198 Self::Dictionary(d) => {
133 let mut bb = [b'd']; 199 let mut bb = [b'd'];
134 w.write_all(&bb)?; 200 w.write_all(&bb)?;
135 for (k, v) in d { 201 for (k, v) in d {
136 (Value::ByteString( k.clone().into_bytes() )).write( w )?; 202 (Value::ByteString(k.clone().into_bytes())).write(w)?;
137 v.write( w )?; 203 v.write(w)?;
138 } 204 }
139 bb[0] = b'e'; 205 bb[0] = b'e';
140 w.write_all(&bb)?; 206 w.write_all(&bb)?;
141 }, 207 }
142 Self::Float(f) => { 208 Self::Float(f) => {
143 match f.classify() { 209 match f.classify() {
144 FpCategory::Nan => { 210 FpCategory::Nan => {
145 let mut bb = [b'F', 0u8]; 211 let mut bb = [b'F', 0u8];
146 bb[1] = if f.is_sign_negative() { 'N' } else { 'n' } as u8; 212 bb[1] = if f.is_sign_negative() { 'N' } else { 'n' } as u8;
147 w.write_all( &bb )?; 213 w.write_all(&bb)?;
148 }, 214 }
149 FpCategory::Infinite => { 215 FpCategory::Infinite => {
150 let mut bb = [b'F', 0u8]; 216 let mut bb = [b'F', 0u8];
151 bb[1] = if f.is_sign_negative() { 'I' } else { 'i' } as u8; 217 bb[1] = if f.is_sign_negative() { 'I' } else { 'i' } as u8;
152 w.write_all( &bb )?; 218 w.write_all(&bb)?;
153 }, 219 }
154 FpCategory::Zero => { 220 FpCategory::Zero => {
155 let mut bb = [b'F', 0u8]; 221 let mut bb = [b'F', 0u8];
156 bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; 222 bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8;
157 w.write_all( &bb )?; 223 w.write_all(&bb)?;
158 }, 224 }
159 FpCategory::Subnormal => { 225 FpCategory::Subnormal => {
160 let mut bb = [b'F', 0u8]; 226 let mut bb = [b'F', 0u8];
161 // The format doesn't account for these...uh...make them zero? 227 // The format doesn't account for these...uh...make them zero?
162 bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8; 228 bb[1] = if f.is_sign_negative() { 'Z' } else { 'z' } as u8;
163 w.write_all( &bb )?; 229 w.write_all(&bb)?;
164 }, 230 }
165 FpCategory::Normal => { 231 FpCategory::Normal => {
166 let bb = [b'f']; 232 let bb = [b'f'];
167 w.write_all( &bb )?; 233 w.write_all(&bb)?;
168 let mut bin = Vec::<u8>::with_capacity(10); 234 let mut bin = Vec::<u8>::with_capacity(10);
169 let (negative, d) = if f.is_sign_negative() { (true, -*f) } else { (false, *f) }; 235 let (negative, d) = if f.is_sign_negative() {
170 let scale : i64 = (d.ln() / *FLOAT_DIVISOR) as i64; 236 (true, -*f)
237 } else {
238 (false, *f)
239 };
240 let scale: i64 = (d.ln() / *FLOAT_DIVISOR) as i64;
171 let scale = if scale < 0 { -1 } else { scale }; 241 let scale = if scale < 0 { -1 } else { scale };
172 let mut d = d / 256.0_f64.powf( scale as f64 ); 242 let mut d = d / 256.0_f64.powf(scale as f64);
173 bin.push( d as u8 ); 243 bin.push(d as u8);
174 d = d.fract(); 244 d = d.fract();
175 for _ in 0..15 { 245 for _ in 0..15 {
176 d *= 256.0; 246 d *= 256.0;
177 bin.push( d as u8 ); 247 bin.push(d as u8);
178 d = d.fract(); 248 d = d.fract();
179 if d == 0.0 { 249 if d == 0.0 {
180 break; 250 break;
181 } 251 }
182 } 252 }
183 if negative { 253 if negative {
184 w.write_all( &write_packed_int( -(bin.len() as i64) ) )?; 254 w.write_all(&write_packed_int(-(bin.len() as i64)))?;
185 } else { 255 } else {
186 w.write_all( &write_packed_int( bin.len() as i64 ) )?; 256 w.write_all(&write_packed_int(bin.len() as i64))?;
187 } 257 }
188 w.write_all( &bin )?; 258 w.write_all(&bin)?;
189 w.write_all( &write_packed_int( scale ) )?; 259 w.write_all(&write_packed_int(scale))?;
190 }, 260 }
191 } 261 }
192 }, 262 }
193 Self::Nothing => { 263 Self::Null => {
194 let bb = [b'n']; 264 let bb = [b'n'];
195 w.write_all( &bb )?; 265 w.write_all(&bb)?;
196 }, 266 }
197 } 267 }
198 Ok(()) 268 Ok(())
199 } 269 }
@@ -201,19 +271,19 @@ impl Value {
201 fn read_parse<R: Read>(r: &mut R) -> Result<ValueParse, Error> { 271 fn read_parse<R: Read>(r: &mut R) -> Result<ValueParse, Error> {
202 let it = { 272 let it = {
203 let mut it = [0u8]; 273 let mut it = [0u8];
204 r.read_exact( &mut it )?; 274 r.read_exact(&mut it)?;
205 it[0] 275 it[0]
206 }; 276 };
207 match it as char { 277 match it as char {
208 '0' => Ok(ValueParse::Value(Value::Boolean(false))), 278 '0' => Ok(ValueParse::Value(Value::Boolean(false))),
209 '1' => Ok(ValueParse::Value(Value::Boolean(true))), 279 '1' => Ok(ValueParse::Value(Value::Boolean(true))),
210 'n' => Ok(ValueParse::Value(Value::Nothing)), 280 'n' => Ok(ValueParse::Value(Value::Null)),
211 'e' => Ok(ValueParse::EndMarker), 281 'e' => Ok(ValueParse::EndMarker),
212 'i' => Ok(ValueParse::Value(Value::Integer(read_packed_int(r)?))), 282 'i' => Ok(ValueParse::Value(Value::Integer(read_packed_int(r)?))),
213 's' => { 283 's' => {
214 let len = read_packed_int(r)?; 284 let len = read_packed_int(r)?;
215 let mut body = vec![0; len as usize]; 285 let mut body = vec![0; len as usize];
216 r.read_exact( &mut body )?; 286 r.read_exact(&mut body)?;
217 Ok(ValueParse::Value(Value::ByteString(body))) 287 Ok(ValueParse::Value(Value::ByteString(body)))
218 } 288 }
219 'l' => { 289 'l' => {
@@ -225,22 +295,18 @@ impl Value {
225 } 295 }
226 'f' => { 296 'f' => {
227 let (lng, neg) = { 297 let (lng, neg) = {
228 let lng = read_packed_int( r )?; 298 let lng = read_packed_int(r)?;
229 if lng < 0 { 299 if lng < 0 { (-lng, true) } else { (lng, false) }
230 (-lng, true)
231 } else {
232 (lng, false)
233 }
234 }; 300 };
235 let mut value = 0.0f64; 301 let mut value = 0.0f64;
236 let mut buf = vec![0u8; lng as usize]; 302 let mut buf = vec![0u8; lng as usize];
237 r.read_exact( &mut buf )?; 303 r.read_exact(&mut buf)?;
238 for b in buf[1..].iter().rev() { 304 for b in buf[1..].iter().rev() {
239 value = (value+(*b as f64))*(1.0/256.0); 305 value = (value + (*b as f64)) * (1.0 / 256.0);
240 } 306 }
241 value += buf[0] as f64; 307 value += buf[0] as f64;
242 let scale = read_packed_int( r )?; 308 let scale = read_packed_int(r)?;
243 value *= 256.0f64.powi( scale as i32 ); 309 value *= 256.0f64.powi(scale as i32);
244 if neg { 310 if neg {
245 Ok(ValueParse::Value(Value::Float(-value))) 311 Ok(ValueParse::Value(Value::Float(-value)))
246 } else { 312 } else {
@@ -250,7 +316,7 @@ impl Value {
250 'F' => { 316 'F' => {
251 let st = { 317 let st = {
252 let mut st = [0u8]; 318 let mut st = [0u8];
253 r.read_exact( &mut st )?; 319 r.read_exact(&mut st)?;
254 st[0] 320 st[0]
255 }; 321 };
256 match st as char { 322 match st as char {
@@ -260,7 +326,10 @@ impl Value {
260 'i' => Ok(ValueParse::Value(Value::Float(f64::INFINITY))), 326 'i' => Ok(ValueParse::Value(Value::Float(f64::INFINITY))),
261 'Z' => Ok(ValueParse::Value(Value::Float(-0.0f64))), 327 'Z' => Ok(ValueParse::Value(Value::Float(-0.0f64))),
262 'z' => Ok(ValueParse::Value(Value::Float(0.0f64))), 328 'z' => Ok(ValueParse::Value(Value::Float(0.0f64))),
263 _ =>Err(Error::new(ErrorKind::InvalidData, "Unknown exceptional float subtype found.")), 329 _ => Err(Error::new(
330 ErrorKind::InvalidData,
331 "Unknown exceptional float subtype found.",
332 )),
264 } 333 }
265 } 334 }
266 'd' => { 335 'd' => {
@@ -270,102 +339,128 @@ impl Value {
270 if let Ok(s) = String::from_utf8(s) { 339 if let Ok(s) = String::from_utf8(s) {
271 s 340 s
272 } else { 341 } else {
273 return Err(Error::new(ErrorKind::InvalidData, "Keys must be utf8 compatbile strings.")); 342 return Err(Error::new(
343 ErrorKind::InvalidData,
344 "Keys must be utf8 compatible strings.",
345 ));
274 } 346 }
275 } else { 347 } else {
276 return Err(Error::new(ErrorKind::InvalidData, "Non-string cannot be dictionary key.")); 348 return Err(Error::new(
349 ErrorKind::InvalidData,
350 "Non-string cannot be dictionary key.",
351 ));
277 }; 352 };
278 let v = match Value::read_parse(r)? { 353 let v = match Value::read_parse(r)? {
279 ValueParse::Value(v) => v, 354 ValueParse::Value(v) => v,
280 ValueParse::EndMarker => { 355 ValueParse::EndMarker => {
281 return Err(Error::new(ErrorKind::InvalidData, "Premature end marker in dictionary.")); 356 return Err(Error::new(
357 ErrorKind::InvalidData,
358 "Premature end marker in dictionary.",
359 ));
282 } 360 }
283 }; 361 };
284 body.insert( k, v ); 362 body.insert(k, v);
285 } 363 }
286 Ok(ValueParse::Value(Value::Dictionary(body))) 364 Ok(ValueParse::Value(Value::Dictionary(body)))
287 } 365 }
288 _ => { 366 _ => Err(Error::new(
289 Err(Error::new(ErrorKind::InvalidData, "Invalid data type specified.")) 367 ErrorKind::InvalidData,
290 } 368 "Invalid data type specified.",
369 )),
291 } 370 }
292 } 371 }
293 372
294 pub fn read<R: Read>(r: &mut R) -> Result<Value, Error> { 373 pub fn read<R: Read>(r: &mut R) -> Result<Value, Error> {
295 match Value::read_parse(r) { 374 match Value::read_parse(r) {
296 Ok(ValueParse::Value(v)) => Ok(v), 375 Ok(ValueParse::Value(v)) => Ok(v),
297 Ok(ValueParse::EndMarker) => Err(Error::new(ErrorKind::InvalidData, "Unexpecetd EndMarker while parsing structure.")), 376 Ok(ValueParse::EndMarker) => Err(Error::new(
298 Err(e) => Err(e) 377 ErrorKind::InvalidData,
378 "Unexpected EndMarker while parsing structure.",
379 )),
380 Err(e) => Err(e),
299 } 381 }
300 } 382 }
301 383
302 pub fn to_packet( &self ) -> Result<Vec<u8>, Error> { 384 pub fn to_packet(&self) -> Result<Vec<u8>, Error> {
303 let mut body : Vec<u8> = vec![1u8,0u8,0u8,0u8,0u8]; 385 let mut body: Vec<u8> = vec![1u8, 0u8, 0u8, 0u8, 0u8];
304 self.write( &mut body )?; 386 self.write(&mut body)?;
305 let len = body.len() as u32; 387 let len = body.len() as u32;
306 body[1..5].copy_from_slice( &len.to_be_bytes() ); 388 body[1..5].copy_from_slice(&len.to_be_bytes());
307 Ok(body) 389 Ok(body)
308 } 390 }
309 391
310 pub fn write_packet<W: Write>( &self, w: &mut W ) -> Result<(), Error> { 392 pub fn write_packet<W: Write>(&self, w: &mut W) -> Result<(), Error> {
311 match self.to_packet() { 393 match self.to_packet() {
312 Ok(body) => { 394 Ok(body) => w.write_all(&body),
313 w.write_all( &body ) 395 Err(e) => Err(e),
314 }
315 Err(e) => {
316 Err(e)
317 }
318 } 396 }
319 } 397 }
320 398
321 pub fn bytes_to_read( r: &[u8] ) -> Result<BytesToRead, Error> { 399 pub fn bytes_to_read(r: &[u8]) -> Result<BytesToRead, Error> {
322 if r.len() < 5 { 400 if r.len() < 5 {
323 Ok(BytesToRead::Estimate(5)) 401 Ok(BytesToRead::Estimate(5))
324 } else { 402 } else {
325 if r[0] != 1 { 403 if r[0] != 1 {
326 return Err(Error::new(ErrorKind::InvalidData, "Invalid gats packet version.")); 404 return Err(Error::new(
405 ErrorKind::InvalidData,
406 "Invalid Gats packet version.",
407 ));
327 } 408 }
328 if let Ok(ar) = r[1..5].try_into() { 409 if let Ok(ar) = r[1..5].try_into() {
329 Ok(BytesToRead::Final(i32::from_be_bytes( ar ) as usize)) 410 Ok(BytesToRead::Final(i32::from_be_bytes(ar) as usize))
330 } else { 411 } else {
331 Err(Error::new(ErrorKind::UnexpectedEof, "Insufficient data presented to decode packet header.")) 412 Err(Error::new(
413 ErrorKind::UnexpectedEof,
414 "Insufficient data presented to decode packet header.",
415 ))
332 } 416 }
333 } 417 }
334 } 418 }
335 419
336 pub fn from_packet( r: &[u8] ) -> Result<Value, Error> { 420 pub fn from_packet(r: &[u8]) -> Result<Value, Error> {
337 if r.len() < 5 { 421 if r.len() < 5 {
338 return Err(Error::new(ErrorKind::UnexpectedEof, "Insufficient data presented to decode packet header.")); 422 return Err(Error::new(
423 ErrorKind::UnexpectedEof,
424 "Insufficient data presented to decode packet header.",
425 ));
339 } 426 }
340 if r[0] != 1 { 427 if r[0] != 1 {
341 return Err(Error::new(ErrorKind::InvalidData, "Invalid gats packet version.")); 428 return Err(Error::new(
429 ErrorKind::InvalidData,
430 "Invalid Gats packet version.",
431 ));
342 } 432 }
343 let size = if let Ok(ar) = r[1..5].try_into() { 433 let size = if let Ok(ar) = r[1..5].try_into() {
344 i32::from_be_bytes( ar ) 434 i32::from_be_bytes(ar)
345 } else { 435 } else {
346 return Err(Error::new(ErrorKind::UnexpectedEof, "Insufficient data presented to decode packet header.")); 436 return Err(Error::new(
437 ErrorKind::UnexpectedEof,
438 "Insufficient data presented to decode packet header.",
439 ));
347 }; 440 };
348 if r.len() != size as usize { 441 if r.len() != size as usize {
349 return Err(Error::new(ErrorKind::InvalidData, "Packet buffer is the wrong length.")); 442 return Err(Error::new(
443 ErrorKind::InvalidData,
444 "Packet buffer is the wrong length.",
445 ));
350 } 446 }
351 Value::read( &mut Cursor::new( &r[5..] ) ) 447 Value::read(&mut Cursor::new(&r[5..]))
352 } 448 }
353 449
354 pub fn read_packet<R: Read>( r: &mut R ) -> Result<Value,Error> { 450 pub fn read_packet<R: Read>(r: &mut R) -> Result<Value, Error> {
355 let mut buf = Vec::<u8>::new(); 451 let mut buf = Vec::<u8>::new();
356 let mut fill = 0usize; 452 let mut fill = 0usize;
357 loop { 453 loop {
358 match Value::bytes_to_read( &buf ) { 454 match Value::bytes_to_read(&buf) {
359 Ok(BytesToRead::Estimate(size)) => { 455 Ok(BytesToRead::Estimate(size)) => {
360 buf.resize(size, 0u8); 456 buf.resize(size, 0u8);
361 r.read_exact( &mut buf[fill..] )?; 457 r.read_exact(&mut buf[fill..])?;
362 fill = buf.len(); 458 fill = buf.len();
363 } 459 }
364 Ok(BytesToRead::Final(size)) => { 460 Ok(BytesToRead::Final(size)) => {
365 buf.resize(size, 0u8); 461 buf.resize(size, 0u8);
366 r.read_exact( &mut buf[fill..] )?; 462 r.read_exact(&mut buf[fill..])?;
367 //fill = buf.len(); 463 return Value::from_packet(&buf);
368 return Value::from_packet( &buf );
369 } 464 }
370 Err(e) => { 465 Err(e) => {
371 return Err(e); 466 return Err(e);
@@ -375,6 +470,24 @@ impl Value {
375 } 470 }
376} 471}
377 472
473impl From<i64> for Value {
474 fn from(v: i64) -> Self {
475 Value::Integer(v)
476 }
477}
478
479impl From<f64> for Value {
480 fn from(v: f64) -> Self {
481 Value::Float(v)
482 }
483}
484
485impl From<bool> for Value {
486 fn from(v: bool) -> Self {
487 Value::Boolean(v)
488 }
489}
490
378#[cfg(test)] 491#[cfg(test)]
379mod tests { 492mod tests {
380 use super::*; 493 use super::*;
@@ -383,97 +496,120 @@ mod tests {
383 use std::io::Cursor; 496 use std::io::Cursor;
384 497
385 #[test] 498 #[test]
386 fn round_int() -> Result<(),Box<dyn Error>> { 499 fn froms() {
500 let v = Value::from(55);
501 assert!(v == 55);
502 let v = Value::from(987.654);
503 assert!(v == 987.654);
504 let v = Value::from(true);
505 assert!(v == true);
506 }
507
508 #[test]
509 fn round_int() -> Result<(), Box<dyn Error>> {
387 let v = Value::Integer(555666); 510 let v = Value::Integer(555666);
388 let mut buf = Vec::<u8>::new(); 511 let mut buf = Vec::<u8>::new();
389 v.write( &mut buf )?; 512 v.write(&mut buf)?;
390 let v2 = Value::read( &mut Cursor::new(buf) )?; 513 let v2 = Value::read(&mut Cursor::new(buf))?;
391 assert!( v == v2 ); 514 assert!(v == v2);
392 assert!( v == 555666 ); 515 assert!(v == 555666);
393 Ok(()) 516 Ok(())
394 } 517 }
395 518
396 #[test] 519 #[test]
397 fn round_str() -> Result<(),Box<dyn Error>> { 520 fn round_str() -> Result<(), Box<dyn Error>> {
398 let v = Value::ByteString(vec![1,1,2,3,5,8,13,21,34]); 521 let v = Value::ByteString(vec![1, 1, 2, 3, 5, 8, 13, 21, 34]);
399 let mut buf = Vec::<u8>::new(); 522 let mut buf = Vec::<u8>::new();
400 v.write( &mut buf )?; 523 v.write(&mut buf)?;
401 let v2 = Value::read( &mut Cursor::new(buf) )?; 524 let v2 = Value::read(&mut Cursor::new(buf))?;
402 let v3 = Value::ByteString(vec![1,1,2,3,5,8,13,21,35]); 525 let v3 = Value::ByteString(vec![1, 1, 2, 3, 5, 8, 13, 21, 35]);
403 assert!( v == v2 ); 526 assert!(v == v2);
404 assert!( v != v3 ); 527 assert!(v != v3);
405 assert!( v == vec![1,1,2,3,5,8,13,21,34] ); 528 assert!(v == vec![1, 1, 2, 3, 5, 8, 13, 21, 34]);
406 Ok(()) 529 Ok(())
407 } 530 }
408 531
409 #[test] 532 #[test]
410 fn round_bool_true() -> Result<(),Box<dyn Error>> { 533 fn round_bool_true() -> Result<(), Box<dyn Error>> {
411 let v = Value::Boolean(true); 534 let v = Value::Boolean(true);
412 let mut buf = Vec::<u8>::new(); 535 let mut buf = Vec::<u8>::new();
413 v.write( &mut buf )?; 536 v.write(&mut buf)?;
414 let v2 = Value::read( &mut Cursor::new(buf) )?; 537 let v2 = Value::read(&mut Cursor::new(buf))?;
415 let v3 = Value::Boolean(false); 538 let v3 = Value::Boolean(false);
416 assert!( v == v2 ); 539 assert!(v == v2);
417 assert!( v != v3 ); 540 assert!(v != v3);
418 assert!( v == true ); 541 assert!(v == true);
419 Ok(()) 542 Ok(())
420 } 543 }
421 544
422 #[test] 545 #[test]
423 fn round_bool_false() -> Result<(),Box<dyn Error>> { 546 fn round_bool_false() -> Result<(), Box<dyn Error>> {
424 let v = Value::Boolean(false); 547 let v = Value::Boolean(false);
425 let mut buf = Vec::<u8>::new(); 548 let mut buf = Vec::<u8>::new();
426 v.write( &mut buf )?; 549 v.write(&mut buf)?;
427 let v2 = Value::read( &mut Cursor::new(buf) )?; 550 let v2 = Value::read(&mut Cursor::new(buf))?;
428 let v3 = Value::Boolean(true); 551 let v3 = Value::Boolean(true);
429 assert!( v == v2 ); 552 assert!(v == v2);
430 assert!( v != v3 ); 553 assert!(v != v3);
431 assert!( v == false ); 554 assert!(v == false);
432 Ok(()) 555 Ok(())
433 } 556 }
434 557
435 #[test] 558 #[test]
436 fn round_list() -> Result<(),Box<dyn Error>> { 559 fn round_list() -> Result<(), Box<dyn Error>> {
437 let v = Value::List(vec![ 560 let v = Value::List(vec![
438 Value::Integer(1), Value::Integer(1), Value::Integer(2), 561 Value::Integer(1),
439 Value::Integer(3), Value::Integer(5), Value::Integer(8), 562 Value::Integer(1),
440 Value::Integer(13), Value::Integer(21), Value::Integer(34), 563 Value::Integer(2),
564 Value::Integer(3),
565 Value::Integer(5),
566 Value::Integer(8),
567 Value::Integer(13),
568 Value::Integer(21),
569 Value::Integer(34),
441 ]); 570 ]);
442 let mut buf = Vec::<u8>::new(); 571 let mut buf = Vec::<u8>::new();
443 v.write( &mut buf )?; 572 v.write(&mut buf)?;
444 let v2 = Value::read( &mut Cursor::new(buf) )?; 573 let v2 = Value::read(&mut Cursor::new(buf))?;
445 assert!( v == v2 ); 574 assert!(v == v2);
446 Ok(()) 575 Ok(())
447 } 576 }
448 577
449 #[test] 578 #[test]
450 fn round_dictionary() -> Result<(), Box<dyn Error>> { 579 fn round_dictionary() -> Result<(), Box<dyn Error>> {
451 let v = Value::Dictionary(HashMap::from([ 580 let v = Value::Dictionary(HashMap::from([
452 ("biggerint".to_string(), Value::Integer(98765)), 581 ("bigger-int".to_string(), Value::Integer(98765)),
453 ("negint".to_string(), Value::Integer(-98765)), 582 ("neg-int".to_string(), Value::Integer(-98765)),
454 ("integer".to_string(), Value::Integer(44)), 583 ("integer".to_string(), Value::Integer(44)),
455 ("boolean".to_string(), Value::Boolean(true)), 584 ("boolean".to_string(), Value::Boolean(true)),
456 ("list".to_string(), Value::List(vec![ 585 (
457 Value::Integer(1), Value::Integer(1), Value::Integer(2), 586 "list".to_string(),
458 Value::Integer(3), Value::Integer(5), Value::Integer(8), 587 Value::List(vec![
459 ])), 588 Value::Integer(1),
460 ("null".to_string(), Value::Nothing), 589 Value::Integer(1),
590 Value::Integer(2),
591 Value::Integer(3),
592 Value::Integer(5),
593 Value::Integer(8),
594 ]),
595 ),
596 ("null".to_string(), Value::Null),
461 ("float".to_string(), Value::Float(123.456)), 597 ("float".to_string(), Value::Float(123.456)),
462 ])); 598 ]));
463 let mut buf = Vec::<u8>::new(); 599 let mut buf = Vec::<u8>::new();
464 v.write( &mut buf )?; 600 v.write(&mut buf)?;
465 let v2 = Value::read( &mut Cursor::new(buf) )?; 601 let v2 = Value::read(&mut Cursor::new(buf))?;
466 assert!( v == v2 ); 602 assert!(v == v2);
467 Ok(()) 603 Ok(())
468 } 604 }
469 605
470 #[test] 606 #[test]
471 fn round_null() -> Result<(), Box<dyn Error>> { 607 fn round_null() -> Result<(), Box<dyn Error>> {
472 let v = Value::Nothing; 608 let v = Value::Null;
473 let mut buf = Vec::<u8>::new(); 609 let mut buf = Vec::<u8>::new();
474 v.write( &mut buf )?; 610 v.write(&mut buf)?;
475 let v2 = Value::read( &mut Cursor::new(buf) )?; 611 let v2 = Value::read(&mut Cursor::new(buf))?;
476 assert!( v == v2 ); 612 assert!(v == v2);
477 Ok(()) 613 Ok(())
478 } 614 }
479 615
@@ -481,29 +617,36 @@ mod tests {
481 fn round_float() -> Result<(), Box<dyn Error>> { 617 fn round_float() -> Result<(), Box<dyn Error>> {
482 let v = Value::Float(123.456); 618 let v = Value::Float(123.456);
483 let mut buf = Vec::<u8>::new(); 619 let mut buf = Vec::<u8>::new();
484 v.write( &mut buf )?; 620 v.write(&mut buf)?;
485 let v2 = Value::read( &mut Cursor::new(buf) )?; 621 let v2 = Value::read(&mut Cursor::new(buf))?;
486 assert!( v == v2 ); 622 assert!(v == v2);
487 Ok(()) 623 Ok(())
488 } 624 }
489 625
490 #[test] 626 #[test]
491 fn packet_1() -> Result<(), Box<dyn Error>> { 627 fn packet_1() -> Result<(), Box<dyn Error>> {
492 let v = Value::Dictionary(HashMap::from([ 628 let v = Value::Dictionary(HashMap::from([
493 ("biggerint".to_string(), Value::Integer(98765)), 629 ("bigger-int".to_string(), Value::Integer(98765)),
494 ("negint".to_string(), Value::Integer(-98765)), 630 ("neg-int".to_string(), Value::Integer(-98765)),
495 ("integer".to_string(), Value::Integer(44)), 631 ("integer".to_string(), Value::Integer(44)),
496 ("boolean".to_string(), Value::Boolean(true)), 632 ("boolean".to_string(), Value::Boolean(true)),
497 ("list".to_string(), Value::List(vec![ 633 (
498 Value::Integer(1), Value::Integer(1), Value::Integer(2), 634 "list".to_string(),
499 Value::Integer(3), Value::Integer(5), Value::Integer(8), 635 Value::List(vec![
500 ])), 636 Value::Integer(1),
501 ("null".to_string(), Value::Nothing), 637 Value::Integer(1),
638 Value::Integer(2),
639 Value::Integer(3),
640 Value::Integer(5),
641 Value::Integer(8),
642 ]),
643 ),
644 ("null".to_string(), Value::Null),
502 ("float".to_string(), Value::Float(123.456)), 645 ("float".to_string(), Value::Float(123.456)),
503 ])); 646 ]));
504 let buf = v.to_packet()?; 647 let buf = v.to_packet()?;
505 let v2 = Value::from_packet( &buf )?; 648 let v2 = Value::from_packet(&buf)?;
506 assert!( v == v2 ); 649 assert!(v == v2);
507 Ok(()) 650 Ok(())
508 } 651 }
509} 652}