kiwi_schema/
lib.rs

1//! This is a Rust library with some helper routines for parsing files in the
2//! Kiwi serialization format. See [https://github.com/evanw/kiwi](https://github.com/evanw/kiwi)
3//! for documentation about the format.
4//!
5//! ```
6//! use kiwi_schema::*;
7//!
8//! let schema = Schema::new(vec![
9//!     Def::new("Point".to_owned(), DefKind::Struct, vec![
10//!         Field {name: "x".to_owned(), type_id: TYPE_FLOAT, is_array: false, value: 0},
11//!         Field {name: "y".to_owned(), type_id: TYPE_FLOAT, is_array: false, value: 0},
12//!     ]),
13//! ]);
14//!
15//! let value = Value::decode(&schema, 0, &[126, 0, 0, 0, 126, 1, 0, 0]).unwrap();
16//! assert_eq!(format!("{:?}", value), "Point {x: 0.5, y: -0.5}");
17//! assert_eq!(value.encode(&schema), [126, 0, 0, 0, 126, 1, 0, 0]);
18//! ```
19
20use std::borrow::Cow;
21use std::collections::HashMap;
22use std::f32;
23use std::fmt;
24use std::ops::Index;
25use std::str;
26
27/// A Kiwi byte buffer meant for reading.
28///
29/// Example usage:
30///
31/// ```
32/// use std::borrow::Cow;
33/// let mut bb = kiwi_schema::ByteBuffer::new(&[240, 159, 141, 149, 0, 133, 242, 210, 237]);
34/// assert_eq!(bb.read_string(), Ok(Cow::Borrowed("🍕")));
35/// assert_eq!(bb.read_var_float(), Ok(123.456));
36/// ```
37///
38pub struct ByteBuffer<'a> {
39    data: &'a [u8],
40    index: usize,
41}
42
43impl<'a> ByteBuffer<'a> {
44    /// Create a new ByteBuffer that wraps the provided byte slice. The lifetime
45    /// of the returned ByteBuffer must not outlive the lifetime of the byte
46    /// slice.
47    pub fn new(data: &[u8]) -> ByteBuffer {
48        ByteBuffer { data, index: 0 }
49    }
50
51    /// Retrieves the underlying byte slice.
52    pub fn data(&self) -> &'a [u8] {
53        self.data
54    }
55
56    /// Retrieves the current index into the underlying byte slice. This starts
57    /// off as 0 and ends up as `self.data().len()` when everything has been
58    /// read.
59    pub fn index(&self) -> usize {
60        self.index
61    }
62
63    /// Try to read a boolean value starting at the current index.
64    pub fn read_bool(&mut self) -> Result<bool, ()> {
65        match self.read_byte() {
66            Ok(0) => Ok(false),
67            Ok(1) => Ok(true),
68            _ => Err(()),
69        }
70    }
71
72    /// Try to read a byte starting at the current index.
73    pub fn read_byte(&mut self) -> Result<u8, ()> {
74        if self.index >= self.data.len() {
75            Err(())
76        } else {
77            let value = self.data[self.index];
78            self.index = self.index + 1;
79            Ok(value)
80        }
81    }
82
83    /// Try to read a byte starting at the current index.
84    pub fn read_bytes(&mut self, len: usize) -> Result<&'a [u8], ()> {
85        if self.index + len > self.data.len() {
86            Err(())
87        } else {
88            let value = &self.data[self.index..self.index + len];
89            self.index = self.index + len;
90            Ok(value)
91        }
92    }
93
94    /// Try to read a variable-length signed 32-bit integer starting at the
95    /// current index.
96    pub fn read_var_int(&mut self) -> Result<i32, ()> {
97        let value = self.read_var_uint()?;
98        Ok((if (value & 1) != 0 {
99            !(value >> 1)
100        } else {
101            value >> 1
102        }) as i32)
103    }
104
105    /// Try to read a variable-length unsigned 32-bit integer starting at the
106    /// current index.
107    pub fn read_var_uint(&mut self) -> Result<u32, ()> {
108        let mut shift: u8 = 0;
109        let mut result: u32 = 0;
110
111        loop {
112            let byte = self.read_byte()?;
113            result |= ((byte & 127) as u32) << shift;
114            shift += 7;
115
116            if (byte & 128) == 0 || shift >= 35 {
117                break;
118            }
119        }
120
121        Ok(result)
122    }
123
124    /// Try to read a variable-length 32-bit floating-point number starting at
125    /// the current index.
126    pub fn read_var_float(&mut self) -> Result<f32, ()> {
127        let first = self.read_byte()?;
128
129        // Optimization: use a single byte to store zero
130        if first == 0 {
131            Ok(0.0)
132        } else if self.index + 3 > self.data.len() {
133            Err(())
134        }
135        // Endian-independent 32-bit read
136        else {
137            let mut bits: u32 = first as u32
138                | ((self.data[self.index] as u32) << 8)
139                | ((self.data[self.index + 1] as u32) << 16)
140                | ((self.data[self.index + 2] as u32) << 24);
141            self.index += 3;
142
143            // Move the exponent back into place
144            bits = (bits << 23) | (bits >> 9);
145
146            Ok(f32::from_bits(bits))
147        }
148    }
149
150    /// Try to read a UTF-8 string starting at the current index. This string is
151    /// returned as a slice so it just aliases the underlying memory.
152    pub fn read_string(&mut self) -> Result<Cow<'a, str>, ()> {
153        let start = self.index;
154
155        while self.index < self.data.len() {
156            if self.data[self.index] == 0 {
157                self.index += 1;
158                return Ok(String::from_utf8_lossy(&self.data[start..self.index - 1]));
159            }
160
161            self.index += 1;
162        }
163
164        Err(())
165    }
166
167    /// Try to read a variable-length signed 64-bit integer starting at the
168    /// current index.
169    pub fn read_var_int64(&mut self) -> Result<i64, ()> {
170        let value = self.read_var_uint64()?;
171        Ok((if (value & 1) != 0 {
172            !(value >> 1)
173        } else {
174            value >> 1
175        }) as i64)
176    }
177
178    /// Try to read a variable-length unsigned 64-bit integer starting at the
179    /// current index.
180    pub fn read_var_uint64(&mut self) -> Result<u64, ()> {
181        let mut shift: u8 = 0;
182        let mut result: u64 = 0;
183
184        loop {
185            let byte = self.read_byte()?;
186            if (byte & 128) == 0 || shift >= 56 {
187                result |= (byte as u64) << shift;
188                break;
189            }
190            result |= ((byte & 127) as u64) << shift;
191            shift += 7;
192        }
193
194        Ok(result)
195    }
196}
197
198#[test]
199fn read_bool() {
200    let try = |bytes| ByteBuffer::new(bytes).read_bool();
201    assert_eq!(try(&[]), Err(()));
202    assert_eq!(try(&[0]), Ok(false));
203    assert_eq!(try(&[1]), Ok(true));
204    assert_eq!(try(&[2]), Err(()));
205}
206
207#[test]
208fn read_byte() {
209    let try = |bytes| ByteBuffer::new(bytes).read_byte();
210    assert_eq!(try(&[]), Err(()));
211    assert_eq!(try(&[0]), Ok(0));
212    assert_eq!(try(&[1]), Ok(1));
213    assert_eq!(try(&[254]), Ok(254));
214    assert_eq!(try(&[255]), Ok(255));
215}
216
217#[test]
218fn read_bytes() {
219    let try = |bytes, len| ByteBuffer::new(bytes).read_bytes(len);
220    assert_eq!(try(&[], 0), Ok(vec![].as_slice()));
221    assert_eq!(try(&[], 1), Err(()));
222    assert_eq!(try(&[0], 0), Ok(vec![].as_slice()));
223    assert_eq!(try(&[0], 1), Ok(vec![0].as_slice()));
224    assert_eq!(try(&[0], 2), Err(()));
225
226    let mut bb = ByteBuffer::new(&[1, 2, 3, 4, 5]);
227    assert_eq!(bb.read_bytes(3), Ok(vec![1, 2, 3].as_slice()));
228    assert_eq!(bb.read_bytes(2), Ok(vec![4, 5].as_slice()));
229    assert_eq!(bb.read_bytes(1), Err(()));
230}
231
232#[test]
233fn read_var_int() {
234    let try = |bytes| ByteBuffer::new(bytes).read_var_int();
235    assert_eq!(try(&[]), Err(()));
236    assert_eq!(try(&[0]), Ok(0));
237    assert_eq!(try(&[1]), Ok(-1));
238    assert_eq!(try(&[2]), Ok(1));
239    assert_eq!(try(&[3]), Ok(-2));
240    assert_eq!(try(&[4]), Ok(2));
241    assert_eq!(try(&[127]), Ok(-64));
242    assert_eq!(try(&[128]), Err(()));
243    assert_eq!(try(&[128, 0]), Ok(0));
244    assert_eq!(try(&[128, 1]), Ok(64));
245    assert_eq!(try(&[128, 2]), Ok(128));
246    assert_eq!(try(&[129, 0]), Ok(-1));
247    assert_eq!(try(&[129, 1]), Ok(-65));
248    assert_eq!(try(&[129, 2]), Ok(-129));
249    assert_eq!(try(&[253, 255, 7]), Ok(-65535));
250    assert_eq!(try(&[254, 255, 7]), Ok(65535));
251    assert_eq!(try(&[253, 255, 255, 255, 15]), Ok(-2147483647));
252    assert_eq!(try(&[254, 255, 255, 255, 15]), Ok(2147483647));
253    assert_eq!(try(&[255, 255, 255, 255, 15]), Ok(-2147483648));
254}
255
256#[test]
257fn read_var_uint() {
258    let try = |bytes| ByteBuffer::new(bytes).read_var_uint();
259    assert_eq!(try(&[]), Err(()));
260    assert_eq!(try(&[0]), Ok(0));
261    assert_eq!(try(&[1]), Ok(1));
262    assert_eq!(try(&[2]), Ok(2));
263    assert_eq!(try(&[3]), Ok(3));
264    assert_eq!(try(&[4]), Ok(4));
265    assert_eq!(try(&[127]), Ok(127));
266    assert_eq!(try(&[128]), Err(()));
267    assert_eq!(try(&[128, 0]), Ok(0));
268    assert_eq!(try(&[128, 1]), Ok(128));
269    assert_eq!(try(&[128, 2]), Ok(256));
270    assert_eq!(try(&[129, 0]), Ok(1));
271    assert_eq!(try(&[129, 1]), Ok(129));
272    assert_eq!(try(&[129, 2]), Ok(257));
273    assert_eq!(try(&[253, 255, 7]), Ok(131069));
274    assert_eq!(try(&[254, 255, 7]), Ok(131070));
275    assert_eq!(try(&[253, 255, 255, 255, 15]), Ok(4294967293));
276    assert_eq!(try(&[254, 255, 255, 255, 15]), Ok(4294967294));
277    assert_eq!(try(&[255, 255, 255, 255, 15]), Ok(4294967295));
278}
279
280#[test]
281fn read_var_float() {
282    let try = |bytes| ByteBuffer::new(bytes).read_var_float();
283    assert_eq!(try(&[]), Err(()));
284    assert_eq!(try(&[0]), Ok(0.0));
285    assert_eq!(try(&[133, 242, 210, 237]), Ok(123.456));
286    assert_eq!(try(&[133, 243, 210, 237]), Ok(-123.456));
287    assert_eq!(try(&[254, 255, 255, 255]), Ok(f32::MIN));
288    assert_eq!(try(&[254, 254, 255, 255]), Ok(f32::MAX));
289    assert_eq!(try(&[1, 1, 0, 0]), Ok(-f32::MIN_POSITIVE));
290    assert_eq!(try(&[1, 0, 0, 0]), Ok(f32::MIN_POSITIVE));
291    assert_eq!(try(&[255, 1, 0, 0]), Ok(f32::NEG_INFINITY));
292    assert_eq!(try(&[255, 0, 0, 0]), Ok(f32::INFINITY));
293    assert_eq!(try(&[255, 0, 0, 128]).map(|f| f.is_nan()), Ok(true));
294}
295
296#[test]
297fn read_string() {
298    let try = |bytes| ByteBuffer::new(bytes).read_string();
299    assert_eq!(try(&[]), Err(()));
300    assert_eq!(try(&[0]), Ok(Cow::Borrowed("")));
301    assert_eq!(try(&[97]), Err(()));
302    assert_eq!(try(&[97, 0]), Ok(Cow::Borrowed("a")));
303    assert_eq!(try(&[97, 98, 99, 0]), Ok(Cow::Borrowed("abc")));
304    assert_eq!(try(&[240, 159, 141, 149, 0]), Ok(Cow::Borrowed("🍕")));
305    assert_eq!(
306        try(&[97, 237, 160, 188, 99, 0]),
307        Ok(Cow::Owned("a���c".to_owned()))
308    );
309}
310
311#[test]
312fn read_var_int64() {
313    let try = |bytes| ByteBuffer::new(bytes).read_var_int64();
314    assert_eq!(try(&[]), Err(()));
315    assert_eq!(try(&[0]), Ok(0));
316    assert_eq!(try(&[1]), Ok(-1));
317    assert_eq!(try(&[2]), Ok(1));
318    assert_eq!(try(&[3]), Ok(-2));
319    assert_eq!(try(&[4]), Ok(2));
320    assert_eq!(try(&[127]), Ok(-64));
321    assert_eq!(try(&[128]), Err(()));
322    assert_eq!(try(&[128, 0]), Ok(0));
323    assert_eq!(try(&[128, 1]), Ok(64));
324    assert_eq!(try(&[128, 2]), Ok(128));
325    assert_eq!(try(&[129, 0]), Ok(-1));
326    assert_eq!(try(&[129, 1]), Ok(-65));
327    assert_eq!(try(&[129, 2]), Ok(-129));
328    assert_eq!(try(&[253, 255, 7]), Ok(-65535));
329    assert_eq!(try(&[254, 255, 7]), Ok(65535));
330    assert_eq!(try(&[253, 255, 255, 255, 15]), Ok(-2147483647));
331    assert_eq!(try(&[254, 255, 255, 255, 15]), Ok(2147483647));
332    assert_eq!(try(&[255, 255, 255, 255, 15]), Ok(-2147483648));
333    assert_eq!(
334        try(&[0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88]),
335        Ok(0x4407_0C14_2030_4040)
336    );
337    assert_eq!(
338        try(&[0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x20]),
339        Ok(-0x1000_0000_0000_0001)
340    );
341    assert_eq!(
342        try(&[0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x20]),
343        Ok(0x1000_0000_0000_0001)
344    );
345    assert_eq!(
346        try(&[0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]),
347        Ok(-0x3FFF_FFFF_FFFF_FFFF)
348    );
349    assert_eq!(
350        try(&[0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]),
351        Ok(0x3FFF_FFFF_FFFF_FFFF)
352    );
353    assert_eq!(
354        try(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]),
355        Ok(-0x4000_0000_0000_0000)
356    );
357    assert_eq!(
358        try(&[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80]),
359        Ok(0x4000_0000_0000_0000)
360    );
361    assert_eq!(
362        try(&[0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]),
363        Ok(-0x7FFF_FFFF_FFFF_FFFF)
364    );
365    assert_eq!(
366        try(&[0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]),
367        Ok(0x7FFF_FFFF_FFFF_FFFF)
368    );
369    assert_eq!(
370        try(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]),
371        Ok(-0x8000_0000_0000_0000)
372    );
373}
374
375#[test]
376fn read_var_uint64() {
377    let try = |bytes| ByteBuffer::new(bytes).read_var_uint64();
378    assert_eq!(try(&[]), Err(()));
379    assert_eq!(try(&[0]), Ok(0));
380    assert_eq!(try(&[1]), Ok(1));
381    assert_eq!(try(&[2]), Ok(2));
382    assert_eq!(try(&[3]), Ok(3));
383    assert_eq!(try(&[4]), Ok(4));
384    assert_eq!(try(&[127]), Ok(127));
385    assert_eq!(try(&[128]), Err(()));
386    assert_eq!(try(&[128, 0]), Ok(0));
387    assert_eq!(try(&[128, 1]), Ok(128));
388    assert_eq!(try(&[128, 2]), Ok(256));
389    assert_eq!(try(&[129, 0]), Ok(1));
390    assert_eq!(try(&[129, 1]), Ok(129));
391    assert_eq!(try(&[129, 2]), Ok(257));
392    assert_eq!(try(&[253, 255, 7]), Ok(131069));
393    assert_eq!(try(&[254, 255, 7]), Ok(131070));
394    assert_eq!(try(&[253, 255, 255, 255, 15]), Ok(4294967293));
395    assert_eq!(try(&[254, 255, 255, 255, 15]), Ok(4294967294));
396    assert_eq!(try(&[255, 255, 255, 255, 15]), Ok(4294967295));
397    assert_eq!(
398        try(&[0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88]),
399        Ok(0x880E_1828_4060_8080)
400    );
401    assert_eq!(
402        try(&[0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10]),
403        Ok(0x1000_0000_0000_0001)
404    );
405    assert_eq!(
406        try(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]),
407        Ok(0x7FFF_FFFF_FFFF_FFFF)
408    );
409    assert_eq!(
410        try(&[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80]),
411        Ok(0x8000_0000_0000_0000)
412    );
413    assert_eq!(
414        try(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]),
415        Ok(0xFFFF_FFFF_FFFF_FFFF)
416    );
417}
418
419#[test]
420fn read_sequence() {
421    let mut bb = ByteBuffer::new(&[
422        0, 133, 242, 210, 237, 240, 159, 141, 149, 0, 149, 154, 239, 58,
423    ]);
424    assert_eq!(bb.read_var_float(), Ok(0.0));
425    assert_eq!(bb.read_var_float(), Ok(123.456));
426    assert_eq!(bb.read_string(), Ok(Cow::Borrowed("🍕")));
427    assert_eq!(bb.read_var_uint(), Ok(123456789));
428}
429
430/// A Kiwi byte buffer meant for writing.
431///
432/// Example usage:
433///
434/// ```
435/// let mut bb = kiwi_schema::ByteBufferMut::new();
436/// bb.write_string("🍕");
437/// bb.write_var_float(123.456);
438/// assert_eq!(bb.data(), [240, 159, 141, 149, 0, 133, 242, 210, 237]);
439/// ```
440///
441pub struct ByteBufferMut {
442    data: Vec<u8>,
443}
444
445impl ByteBufferMut {
446    /// Creates an empty ByteBufferMut ready for writing.
447    pub fn new() -> ByteBufferMut {
448        ByteBufferMut { data: vec![] }
449    }
450
451    /// Consumes this buffer and returns the underlying backing store. Use this
452    /// to get the data out when you're done writing to the buffer.
453    pub fn data(self) -> Vec<u8> {
454        self.data
455    }
456
457    /// Returns the number of bytes written so far.
458    pub fn len(&self) -> usize {
459        self.data.len()
460    }
461
462    /// Write a boolean value to the end of the buffer.
463    pub fn write_bool(&mut self, value: bool) {
464        self.data.push(if value { 1 } else { 0 });
465    }
466
467    /// Write a byte to the end of the buffer.
468    pub fn write_byte(&mut self, value: u8) {
469        self.data.push(value);
470    }
471
472    /// Write a raw byte slice to the end of the buffer.
473    pub fn write_bytes(&mut self, value: &[u8]) {
474        self.data.extend_from_slice(value);
475    }
476
477    /// Write a variable-length signed 32-bit integer to the end of the buffer.
478    pub fn write_var_int(&mut self, value: i32) {
479        self.write_var_uint(((value << 1) ^ (value >> 31)) as u32);
480    }
481
482    /// Write a variable-length unsigned 32-bit integer to the end of the buffer.
483    pub fn write_var_uint(&mut self, mut value: u32) {
484        loop {
485            let byte = value as u8 & 127;
486            value >>= 7;
487
488            if value == 0 {
489                self.write_byte(byte);
490                return;
491            }
492
493            self.write_byte(byte | 128);
494        }
495    }
496
497    /// Write a variable-length 32-bit floating-point number to the end of the
498    /// buffer.
499    pub fn write_var_float(&mut self, value: f32) {
500        // Reinterpret as an integer
501        let mut bits = value.to_bits();
502
503        // Move the exponent to the first 8 bits
504        bits = (bits >> 23) | (bits << 9);
505
506        // Optimization: use a single byte to store zero and denormals (try for an exponent of 0)
507        if (bits & 255) == 0 {
508            self.data.push(0);
509            return;
510        }
511
512        // Endian-independent 32-bit write
513        self.data.extend_from_slice(&[
514            bits as u8,
515            (bits >> 8) as u8,
516            (bits >> 16) as u8,
517            (bits >> 24) as u8,
518        ]);
519    }
520
521    /// Write a UTF-8 string to the end of the buffer.
522    pub fn write_string(&mut self, value: &str) {
523        self.data.extend_from_slice(value.as_bytes());
524        self.data.push(0);
525    }
526
527    /// Write a variable-length signed 64-bit integer to the end of the buffer.
528    pub fn write_var_int64(&mut self, value: i64) {
529        self.write_var_uint64(((value << 1) ^ (value >> 63)) as u64);
530    }
531
532    /// Write a variable-length unsigned 64-bit integer to the end of the buffer.
533    pub fn write_var_uint64(&mut self, mut value: u64) {
534        let mut i = 0;
535        while value > 127 && i < 8 {
536            self.write_byte((value as u8 & 127) | 128);
537            value >>= 7;
538            i += 1;
539        }
540        self.write_byte(value as u8);
541    }
542}
543
544#[cfg(test)]
545fn write_once(cb: fn(&mut ByteBufferMut)) -> Vec<u8> {
546    let mut bb = ByteBufferMut::new();
547    cb(&mut bb);
548    bb.data()
549}
550
551#[test]
552fn write_bool() {
553    assert_eq!(write_once(|bb| bb.write_bool(false)), [0]);
554    assert_eq!(write_once(|bb| bb.write_bool(true)), [1]);
555}
556
557#[test]
558fn write_byte() {
559    assert_eq!(write_once(|bb| bb.write_byte(0)), [0]);
560    assert_eq!(write_once(|bb| bb.write_byte(1)), [1]);
561    assert_eq!(write_once(|bb| bb.write_byte(254)), [254]);
562    assert_eq!(write_once(|bb| bb.write_byte(255)), [255]);
563}
564
565#[test]
566fn write_bytes() {
567    let mut bb = ByteBufferMut::new();
568    bb.write_bytes(&[1, 2, 3]);
569    bb.write_bytes(&[]);
570    bb.write_bytes(&[4, 5]);
571    assert_eq!(bb.data(), [1, 2, 3, 4, 5]);
572}
573
574#[test]
575fn write_var_int() {
576    assert_eq!(write_once(|bb| bb.write_var_int(0)), [0]);
577    assert_eq!(write_once(|bb| bb.write_var_int(-1)), [1]);
578    assert_eq!(write_once(|bb| bb.write_var_int(1)), [2]);
579    assert_eq!(write_once(|bb| bb.write_var_int(-2)), [3]);
580    assert_eq!(write_once(|bb| bb.write_var_int(2)), [4]);
581    assert_eq!(write_once(|bb| bb.write_var_int(-64)), [127]);
582    assert_eq!(write_once(|bb| bb.write_var_int(64)), [128, 1]);
583    assert_eq!(write_once(|bb| bb.write_var_int(128)), [128, 2]);
584    assert_eq!(write_once(|bb| bb.write_var_int(-129)), [129, 2]);
585    assert_eq!(write_once(|bb| bb.write_var_int(-65535)), [253, 255, 7]);
586    assert_eq!(write_once(|bb| bb.write_var_int(65535)), [254, 255, 7]);
587    assert_eq!(
588        write_once(|bb| bb.write_var_int(-2147483647)),
589        [253, 255, 255, 255, 15]
590    );
591    assert_eq!(
592        write_once(|bb| bb.write_var_int(2147483647)),
593        [254, 255, 255, 255, 15]
594    );
595    assert_eq!(
596        write_once(|bb| bb.write_var_int(-2147483648)),
597        [255, 255, 255, 255, 15]
598    );
599}
600
601#[test]
602fn write_var_uint() {
603    assert_eq!(write_once(|bb| bb.write_var_uint(0)), [0]);
604    assert_eq!(write_once(|bb| bb.write_var_uint(1)), [1]);
605    assert_eq!(write_once(|bb| bb.write_var_uint(2)), [2]);
606    assert_eq!(write_once(|bb| bb.write_var_uint(3)), [3]);
607    assert_eq!(write_once(|bb| bb.write_var_uint(4)), [4]);
608    assert_eq!(write_once(|bb| bb.write_var_uint(127)), [127]);
609    assert_eq!(write_once(|bb| bb.write_var_uint(128)), [128, 1]);
610    assert_eq!(write_once(|bb| bb.write_var_uint(256)), [128, 2]);
611    assert_eq!(write_once(|bb| bb.write_var_uint(129)), [129, 1]);
612    assert_eq!(write_once(|bb| bb.write_var_uint(257)), [129, 2]);
613    assert_eq!(write_once(|bb| bb.write_var_uint(131069)), [253, 255, 7]);
614    assert_eq!(write_once(|bb| bb.write_var_uint(131070)), [254, 255, 7]);
615    assert_eq!(
616        write_once(|bb| bb.write_var_uint(4294967293)),
617        [253, 255, 255, 255, 15]
618    );
619    assert_eq!(
620        write_once(|bb| bb.write_var_uint(4294967294)),
621        [254, 255, 255, 255, 15]
622    );
623    assert_eq!(
624        write_once(|bb| bb.write_var_uint(4294967295)),
625        [255, 255, 255, 255, 15]
626    );
627}
628
629#[test]
630fn write_var_float() {
631    assert_eq!(write_once(|bb| bb.write_var_float(0.0)), [0]);
632    assert_eq!(write_once(|bb| bb.write_var_float(-0.0)), [0]);
633    assert_eq!(
634        write_once(|bb| bb.write_var_float(123.456)),
635        [133, 242, 210, 237]
636    );
637    assert_eq!(
638        write_once(|bb| bb.write_var_float(-123.456)),
639        [133, 243, 210, 237]
640    );
641    assert_eq!(
642        write_once(|bb| bb.write_var_float(f32::MIN)),
643        [254, 255, 255, 255]
644    );
645    assert_eq!(
646        write_once(|bb| bb.write_var_float(f32::MAX)),
647        [254, 254, 255, 255]
648    );
649    assert_eq!(
650        write_once(|bb| bb.write_var_float(-f32::MIN_POSITIVE)),
651        [1, 1, 0, 0]
652    );
653    assert_eq!(
654        write_once(|bb| bb.write_var_float(f32::MIN_POSITIVE)),
655        [1, 0, 0, 0]
656    );
657    assert_eq!(
658        write_once(|bb| bb.write_var_float(f32::NEG_INFINITY)),
659        [255, 1, 0, 0]
660    );
661    assert_eq!(
662        write_once(|bb| bb.write_var_float(f32::INFINITY)),
663        [255, 0, 0, 0]
664    );
665    assert_eq!(
666        write_once(|bb| bb.write_var_float(f32::NAN)),
667        [255, 0, 0, 128]
668    );
669    assert_eq!(write_once(|bb| bb.write_var_float(1.0e-40)), [0]);
670}
671
672#[test]
673fn write_string() {
674    assert_eq!(write_once(|bb| bb.write_string("")), [0]);
675    assert_eq!(write_once(|bb| bb.write_string("a")), [97, 0]);
676    assert_eq!(write_once(|bb| bb.write_string("abc")), [97, 98, 99, 0]);
677    assert_eq!(
678        write_once(|bb| bb.write_string("🍕")),
679        [240, 159, 141, 149, 0]
680    );
681}
682
683#[test]
684fn write_var_int64() {
685    assert_eq!(write_once(|bb| bb.write_var_int64(0)), [0]);
686    assert_eq!(write_once(|bb| bb.write_var_int64(-1)), [1]);
687    assert_eq!(write_once(|bb| bb.write_var_int64(1)), [2]);
688    assert_eq!(write_once(|bb| bb.write_var_int64(-2)), [3]);
689    assert_eq!(write_once(|bb| bb.write_var_int64(2)), [4]);
690    assert_eq!(write_once(|bb| bb.write_var_int64(-64)), [127]);
691    assert_eq!(write_once(|bb| bb.write_var_int64(64)), [128, 1]);
692    assert_eq!(write_once(|bb| bb.write_var_int64(128)), [128, 2]);
693    assert_eq!(write_once(|bb| bb.write_var_int64(-129)), [129, 2]);
694    assert_eq!(write_once(|bb| bb.write_var_int64(-65535)), [253, 255, 7]);
695    assert_eq!(write_once(|bb| bb.write_var_int64(65535)), [254, 255, 7]);
696    assert_eq!(
697        write_once(|bb| bb.write_var_int64(-2147483647)),
698        [253, 255, 255, 255, 15]
699    );
700    assert_eq!(
701        write_once(|bb| bb.write_var_int64(2147483647)),
702        [254, 255, 255, 255, 15]
703    );
704    assert_eq!(
705        write_once(|bb| bb.write_var_int64(-2147483648)),
706        [255, 255, 255, 255, 15]
707    );
708    assert_eq!(
709        write_once(|bb| bb.write_var_int64(-0x1000_0000_0000_0001)),
710        [0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x20]
711    );
712    assert_eq!(
713        write_once(|bb| bb.write_var_int64(0x1000_0000_0000_0001)),
714        [0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x20]
715    );
716    assert_eq!(
717        write_once(|bb| bb.write_var_int64(-0x3FFF_FFFF_FFFF_FFFF)),
718        [0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]
719    );
720    assert_eq!(
721        write_once(|bb| bb.write_var_int64(0x3FFF_FFFF_FFFF_FFFF)),
722        [0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]
723    );
724    assert_eq!(
725        write_once(|bb| bb.write_var_int64(-0x4000_0000_0000_0000)),
726        [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]
727    );
728    assert_eq!(
729        write_once(|bb| bb.write_var_int64(0x4000_0000_0000_0000)),
730        [0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80]
731    );
732    assert_eq!(
733        write_once(|bb| bb.write_var_int64(-0x7FFF_FFFF_FFFF_FFFF)),
734        [0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
735    );
736    assert_eq!(
737        write_once(|bb| bb.write_var_int64(0x7FFF_FFFF_FFFF_FFFF)),
738        [0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
739    );
740    assert_eq!(
741        write_once(|bb| bb.write_var_int64(-0x8000_0000_0000_0000)),
742        [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
743    );
744}
745
746#[test]
747fn write_var_uint64() {
748    assert_eq!(write_once(|bb| bb.write_var_uint64(0)), [0]);
749    assert_eq!(write_once(|bb| bb.write_var_uint64(1)), [1]);
750    assert_eq!(write_once(|bb| bb.write_var_uint64(2)), [2]);
751    assert_eq!(write_once(|bb| bb.write_var_uint64(3)), [3]);
752    assert_eq!(write_once(|bb| bb.write_var_uint64(4)), [4]);
753    assert_eq!(write_once(|bb| bb.write_var_uint64(127)), [127]);
754    assert_eq!(write_once(|bb| bb.write_var_uint64(128)), [128, 1]);
755    assert_eq!(write_once(|bb| bb.write_var_uint64(256)), [128, 2]);
756    assert_eq!(write_once(|bb| bb.write_var_uint64(129)), [129, 1]);
757    assert_eq!(write_once(|bb| bb.write_var_uint64(257)), [129, 2]);
758    assert_eq!(write_once(|bb| bb.write_var_uint64(131069)), [253, 255, 7]);
759    assert_eq!(write_once(|bb| bb.write_var_uint64(131070)), [254, 255, 7]);
760    assert_eq!(
761        write_once(|bb| bb.write_var_uint64(4294967293)),
762        [253, 255, 255, 255, 15]
763    );
764    assert_eq!(
765        write_once(|bb| bb.write_var_uint64(4294967294)),
766        [254, 255, 255, 255, 15]
767    );
768    assert_eq!(
769        write_once(|bb| bb.write_var_uint64(4294967295)),
770        [255, 255, 255, 255, 15]
771    );
772    assert_eq!(
773        write_once(|bb| bb.write_var_uint64(0x1000_0000_0000_0001)),
774        [0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10]
775    );
776    assert_eq!(
777        write_once(|bb| bb.write_var_uint64(0x7FFF_FFFF_FFFF_FFFF)),
778        [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]
779    );
780    assert_eq!(
781        write_once(|bb| bb.write_var_uint64(0x8000_0000_0000_0000)),
782        [0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80]
783    );
784    assert_eq!(
785        write_once(|bb| bb.write_var_uint64(0xFFFF_FFFF_FFFF_FFFF)),
786        [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
787    );
788}
789
790#[test]
791fn write_sequence() {
792    let mut bb = ByteBufferMut::new();
793    bb.write_var_float(0.0);
794    bb.write_var_float(123.456);
795    bb.write_string("🍕");
796    bb.write_var_uint(123456789);
797    assert_eq!(
798        bb.data(),
799        [0, 133, 242, 210, 237, 240, 159, 141, 149, 0, 149, 154, 239, 58]
800    );
801}
802
803pub const TYPE_BOOL: i32 = -1;
804pub const TYPE_BYTE: i32 = -2;
805pub const TYPE_INT: i32 = -3;
806pub const TYPE_UINT: i32 = -4;
807pub const TYPE_FLOAT: i32 = -5;
808pub const TYPE_STRING: i32 = -6;
809pub const TYPE_INT64: i32 = -7;
810pub const TYPE_UINT64: i32 = -8;
811
812/// Represents a single field in a [Def](struct.Def.html).
813#[derive(Debug, PartialEq)]
814pub struct Field {
815    /// The name of this field from the textual Kiwi schema.
816    pub name: String,
817
818    /// For user-defined types, this is the index of the [Def](struct.Def.html)
819    /// in the `defs` array of the [Schema](struct.Schema.html).
820    /// Built-in types use special constants:
821    ///
822    /// * [TYPE_BOOL](constant.TYPE_BOOL.html)
823    /// * [TYPE_BYTE](constant.TYPE_BYTE.html)
824    /// * [TYPE_INT](constant.TYPE_INT.html)
825    /// * [TYPE_UINT](constant.TYPE_UINT.html)
826    /// * [TYPE_FLOAT](constant.TYPE_FLOAT.html)
827    /// * [TYPE_STRING](constant.TYPE_STRING.html)
828    /// * [TYPE_INT64](constant.TYPE_INT64.html)
829    /// * [TYPE_UINT64](constant.TYPE_UINT64.html)
830    pub type_id: i32,
831
832    /// True if this field was declared as an array (e.g. `int[]` instead of
833    /// `int` in the textual Kiwi schema). Arrays are encoded using a length
834    /// prefix followed by that many items.
835    pub is_array: bool,
836
837    /// The identifier corresponding to this field. This is the enum value for
838    /// enum definitions and the field id for message definitions. This value has
839    /// no meaning for struct definitions.
840    pub value: u32,
841}
842
843#[derive(Debug, PartialEq, Eq)]
844pub enum DefKind {
845    /// Enums are encoded as variable-length unsigned integers under the hood.
846    /// Declaring one in the textual Kiwi format looks like this:
847    ///
848    /// ```text
849    /// enum Example {
850    ///   A = 100;
851    ///   B = 200;
852    /// }
853    /// ```
854    Enum,
855
856    /// Structs are tuples of fields and are encoded by encoding each field in
857    /// order. All fields are guaranteed to be present. Declaring one in the
858    /// textual Kiwi format looks like this:
859    ///
860    /// ```text
861    /// struct Example {
862    ///   int a;
863    ///   int b;
864    /// }
865    /// ```
866    Struct,
867
868    /// Messages are objects filled with optional fields and are encoded as a
869    /// sequence of (id, value) pairs followed by a zero byte. All fields are
870    /// optional and may not be present. Declaring one in the textual Kiwi format
871    /// looks like this:
872    ///
873    /// ```text
874    /// message Example {
875    ///   int a = 1;
876    ///   int b = 2;
877    /// }
878    /// ```
879    Message,
880}
881
882pub const DEF_ENUM: u8 = 0;
883pub const DEF_STRUCT: u8 = 1;
884pub const DEF_MESSAGE: u8 = 2;
885
886/// Represents a single definition in a [Schema](struct.Schema.html).
887/// Kiwi enums, structs, and messages are all represented using this object.
888#[derive(Debug, PartialEq)]
889pub struct Def {
890    /// The name of this field from the textual Kiwi schema.
891    pub name: String,
892
893    /// The index of this Def in the `defs` field of the parent
894    /// [Schema](struct.Schema.html). This is used as the type
895    /// identifier for any fields with this type.
896    pub index: i32,
897
898    /// Either [Enum](enum.DefKind.html#variant.Enum),
899    /// [Struct](enum.DefKind.html#variant.Struct), or
900    /// [Message](enum.DefKind.html#variant.Message).
901    pub kind: DefKind,
902
903    /// All fields in this definition. The order matters for struct definitions.
904    pub fields: Vec<Field>,
905
906    /// Maps the `value` and `name` members of each [Field](struct.Field.html) in
907    /// the `fields` array to its index in that array. This is helpful when
908    /// decoding and encoding a field to be able to quickly get to the field
909    /// metadata.
910    pub field_value_to_index: HashMap<u32, usize>,
911    pub field_name_to_index: HashMap<String, usize>,
912}
913
914impl Def {
915    pub fn new(name: String, kind: DefKind, fields: Vec<Field>) -> Def {
916        let mut field_value_to_index = HashMap::new();
917        let mut field_name_to_index = HashMap::new();
918        for (i, field) in fields.iter().enumerate() {
919            field_value_to_index.insert(field.value, i);
920            field_name_to_index.insert(field.name.clone(), i);
921        }
922        Def {
923            name,
924            index: 0,
925            kind,
926            fields,
927            field_value_to_index,
928            field_name_to_index,
929        }
930    }
931
932    /// Returns the [Field](struct.Field.html) with the provided name if one exists.
933    pub fn field(&self, name: &str) -> Option<&Field> {
934        self.field_name_to_index.get(name).map(|i| &self.fields[*i])
935    }
936}
937
938#[derive(Debug, PartialEq)]
939pub struct SchemaOptions {
940    // The Rust implementation is the only one that validates enums while skipping fields.
941    // Ideally all implementations should end up validating enums, but to maintain
942    // compatibility with other clients this can be used to allow enums to be decoded
943    // even if they aren't valid.
944    pub validate_enums: bool,
945}
946
947/// Holds the contents of a Kiwi schema.
948///
949/// Each schema consists of a list of definitions, each of which has a list of
950/// fields. It can either be constructed in memory or decoded from a file in
951/// the binary Kiwi schema format.
952///
953/// Example usage:
954///
955/// ```
956/// // This is the encoding of the Kiwi schema "message ABC { int[] xyz = 1; }"
957/// let schema_bytes = [1, 65, 66, 67, 0, 2, 1, 120, 121, 122, 0, 5, 1, 1];
958/// let schema = kiwi_schema::Schema::decode(&schema_bytes).unwrap();
959///
960/// let def = schema.def("ABC").unwrap();
961/// assert_eq!(def.kind, kiwi_schema::DefKind::Message);
962///
963/// let field = def.field("xyz").unwrap();
964/// assert_eq!(field.type_id, kiwi_schema::TYPE_INT);
965/// assert_eq!(field.is_array, true);
966/// assert_eq!(field.value, 1);
967/// ```
968#[derive(Debug, PartialEq)]
969pub struct Schema {
970    pub defs: Vec<Def>,
971
972    /// Maps the `name` member of each [Def](struct.Def.html) in the `defs` array
973    /// to its index in that array. This is helpful when decoding and encoding a
974    /// field to be able to quickly get to the field metadata.
975    pub def_name_to_index: HashMap<String, usize>,
976}
977
978impl Schema {
979    pub fn new(mut defs: Vec<Def>) -> Schema {
980        let mut def_name_to_index = HashMap::new();
981        for (i, def) in defs.iter_mut().enumerate() {
982            def.index = i as i32;
983            def_name_to_index.insert(def.name.clone(), i);
984        }
985        Schema {
986            defs,
987            def_name_to_index,
988        }
989    }
990
991    /// Parses a Kiwi schema encoded in the binary format and returns the parsed
992    /// schema if successful. A textual schema can be compiled into a binary
993    /// schema using the command-line tools:
994    ///
995    /// ```text
996    /// kiwic --schema example.kiwi --binary example.bkiwi
997    /// ```
998    pub fn decode(bytes: &[u8]) -> Result<Schema, ()> {
999        let mut defs = Vec::new();
1000        let mut bb = ByteBuffer::new(bytes);
1001        let definition_count = bb.read_var_uint()?;
1002
1003        for _ in 0..definition_count {
1004            let name = bb.read_string()?.into_owned();
1005            let kind = match bb.read_byte()? {
1006                DEF_ENUM => DefKind::Enum,
1007                DEF_STRUCT => DefKind::Struct,
1008                DEF_MESSAGE => DefKind::Message,
1009                _ => return Err(()),
1010            };
1011            let field_count = bb.read_var_uint()?;
1012            let mut fields = Vec::new();
1013
1014            for _ in 0..field_count {
1015                let name = bb.read_string()?.into_owned();
1016                let type_id = bb.read_var_int()?;
1017                let is_array = bb.read_bool()?;
1018                let value = bb.read_var_uint()?;
1019                if type_id < TYPE_UINT64 || type_id >= definition_count as i32 {
1020                    return Err(());
1021                }
1022                fields.push(Field {
1023                    name,
1024                    type_id,
1025                    is_array,
1026                    value,
1027                });
1028            }
1029
1030            defs.push(Def::new(name, kind, fields));
1031        }
1032
1033        Ok(Schema::new(defs))
1034    }
1035
1036    /// The opposite of [decode](#method.decode). Turns this schema back into a
1037    /// binary file.
1038    pub fn encode(&self) -> Vec<u8> {
1039        let mut bb = ByteBufferMut::new();
1040        bb.write_var_uint(self.defs.len() as u32);
1041
1042        for def in &self.defs {
1043            bb.write_string(def.name.as_str());
1044            bb.write_byte(match def.kind {
1045                DefKind::Enum => DEF_ENUM,
1046                DefKind::Struct => DEF_STRUCT,
1047                DefKind::Message => DEF_MESSAGE,
1048            });
1049            bb.write_var_uint(def.fields.len() as u32);
1050
1051            for field in &def.fields {
1052                bb.write_string(field.name.as_str());
1053                bb.write_var_int(field.type_id);
1054                bb.write_bool(field.is_array);
1055                bb.write_var_uint(field.value);
1056            }
1057        }
1058
1059        bb.data()
1060    }
1061
1062    /// Returns the [Def](struct.Def.html) with the provided name if one exists.
1063    pub fn def(&self, name: &str) -> Option<&Def> {
1064        self.def_name_to_index.get(name).map(|i| &self.defs[*i])
1065    }
1066
1067    /// Advances the current index of the provided [ByteBuffer](struct.ByteBuffer.html)
1068    /// by the size of a field with the provided type information. The Kiwi format
1069    /// doesn't support seeking around to arbitrary points (it must be read from
1070    /// start to end) so this method is helpful when you need to to skip past
1071    /// unimportant fields.
1072    pub fn skip_with_options(
1073        &self,
1074        bb: &mut ByteBuffer,
1075        type_id: i32,
1076        options: &SchemaOptions,
1077    ) -> Result<(), ()> {
1078        match type_id {
1079            TYPE_BOOL => {
1080                bb.read_bool()?;
1081            }
1082            TYPE_BYTE => {
1083                bb.read_byte()?;
1084            }
1085            TYPE_INT => {
1086                bb.read_var_int()?;
1087            }
1088            TYPE_UINT => {
1089                bb.read_var_uint()?;
1090            }
1091            TYPE_FLOAT => {
1092                bb.read_var_float()?;
1093            }
1094            TYPE_STRING => {
1095                bb.read_string()?;
1096            }
1097            TYPE_INT64 => {
1098                bb.read_var_int64()?;
1099            }
1100            TYPE_UINT64 => {
1101                bb.read_var_uint64()?;
1102            }
1103
1104            _ => {
1105                let def = &self.defs[type_id as usize];
1106
1107                match def.kind {
1108                    DefKind::Enum => {
1109                        if !def.field_value_to_index.contains_key(&bb.read_var_uint()?)
1110                            && options.validate_enums
1111                        {
1112                            return Err(());
1113                        }
1114                    }
1115
1116                    DefKind::Struct => {
1117                        for field in &def.fields {
1118                            self.skip_field_with_options(bb, field, options)?;
1119                        }
1120                    }
1121
1122                    DefKind::Message => loop {
1123                        let value = bb.read_var_uint()?;
1124                        if value == 0 {
1125                            break;
1126                        }
1127                        if let Some(index) = def.field_value_to_index.get(&value) {
1128                            self.skip_field_with_options(bb, &def.fields[*index], options)?;
1129                        } else {
1130                            return Err(());
1131                        }
1132                    },
1133                }
1134            }
1135        }
1136
1137        Ok(())
1138    }
1139
1140    pub fn skip(&self, bb: &mut ByteBuffer, type_id: i32) -> Result<(), ()> {
1141        self.skip_with_options(
1142            bb,
1143            type_id,
1144            &SchemaOptions {
1145                validate_enums: true,
1146            },
1147        )
1148    }
1149
1150    /// Advances the current index of the provided [ByteBuffer](struct.ByteBuffer.html)
1151    /// by the size of the provided field. This is used by [skip](#method.skip)
1152    /// but may also be useful by itself.
1153    pub fn skip_field_with_options(
1154        &self,
1155        bb: &mut ByteBuffer,
1156        field: &Field,
1157        options: &SchemaOptions,
1158    ) -> Result<(), ()> {
1159        if field.is_array {
1160            let len = bb.read_var_uint()? as usize;
1161            for _ in 0..len {
1162                self.skip_with_options(bb, field.type_id, options)?;
1163            }
1164        } else {
1165            self.skip_with_options(bb, field.type_id, options)?;
1166        }
1167        Ok(())
1168    }
1169
1170    pub fn skip_field(&self, bb: &mut ByteBuffer, field: &Field) -> Result<(), ()> {
1171        self.skip_field_with_options(
1172            bb,
1173            field,
1174            &SchemaOptions {
1175                validate_enums: true,
1176            },
1177        )
1178    }
1179}
1180
1181#[test]
1182fn schema_decode_and_encode() {
1183    // This is the encoding of the Kiwi schema "message ABC { int[] xyz = 1; }"
1184    let schema_bytes = [1, 65, 66, 67, 0, 2, 1, 120, 121, 122, 0, 5, 1, 1];
1185    let schema = Schema::decode(&schema_bytes).unwrap();
1186    assert_eq!(
1187        schema,
1188        Schema::new(vec![Def::new(
1189            "ABC".to_owned(),
1190            DefKind::Message,
1191            vec![Field {
1192                name: "xyz".to_owned(),
1193                type_id: TYPE_INT,
1194                is_array: true,
1195                value: 1
1196            },]
1197        ),])
1198    );
1199    assert_eq!(schema.encode(), schema_bytes);
1200}
1201
1202/// This type holds dynamic Kiwi data.
1203///
1204/// Values can represent anything in a Kiwi schema and can be converted to and
1205/// from byte arrays using the corresponding [Schema](struct.Schema.html).
1206/// Enums and field names are stored using string slices from their Schema
1207/// for efficiency. This means that a Value can outlive the buffer it was parsed
1208/// from but can't outlive the schema.
1209#[derive(Clone, PartialEq)]
1210pub enum Value<'a> {
1211    Bool(bool),
1212    Byte(u8),
1213    Int(i32),
1214    UInt(u32),
1215    Float(f32),
1216    String(String),
1217    Int64(i64),
1218    UInt64(u64),
1219    Array(Vec<Value<'a>>),
1220    Enum(&'a str, &'a str),
1221    Object(&'a str, HashMap<&'a str, Value<'a>>),
1222}
1223
1224impl<'a> Value<'a> {
1225    /// A convenience method to extract the value out of a [Bool](#variant.Bool).
1226    /// Returns `false` for other value kinds.
1227    pub fn as_bool(&self) -> bool {
1228        match *self {
1229            Value::Bool(value) => value,
1230            _ => false,
1231        }
1232    }
1233
1234    /// A convenience method to extract the value out of a [Byte](#variant.Byte).
1235    /// Returns `0` for other value kinds.
1236    pub fn as_byte(&self) -> u8 {
1237        match *self {
1238            Value::Byte(value) => value,
1239            _ => 0,
1240        }
1241    }
1242
1243    /// A convenience method to extract the value out of an [Int](#variant.Int).
1244    /// Returns `0` for other value kinds.
1245    pub fn as_int(&self) -> i32 {
1246        match *self {
1247            Value::Int(value) => value,
1248            _ => 0,
1249        }
1250    }
1251
1252    /// A convenience method to extract the value out of a [UInt](#variant.UInt).
1253    /// Returns `0` for other value kinds.
1254    pub fn as_uint(&self) -> u32 {
1255        match *self {
1256            Value::UInt(value) => value,
1257            _ => 0,
1258        }
1259    }
1260
1261    /// A convenience method to extract the value out of a [Float](#variant.Float).
1262    /// Returns `0.0` for other value kinds.
1263    pub fn as_float(&self) -> f32 {
1264        match *self {
1265            Value::Float(value) => value,
1266            _ => 0.0,
1267        }
1268    }
1269
1270    /// A convenience method to extract the value out of a [String](#variant.String).
1271    /// Returns `""` for other value kinds.
1272    pub fn as_string(&self) -> &str {
1273        match *self {
1274            Value::String(ref value) => value.as_str(),
1275            _ => "",
1276        }
1277    }
1278
1279    /// A convenience method to extract the length out of an [Array](#variant.Array).
1280    /// Returns `0` for other value kinds.
1281    pub fn len(&self) -> usize {
1282        match *self {
1283            Value::Array(ref values) => values.len(),
1284            _ => 0,
1285        }
1286    }
1287
1288    /// A convenience method to append to an [Array](#variant.Array). Does
1289    /// nothing for other value kinds.
1290    pub fn push(&mut self, value: Value<'a>) {
1291        if let Value::Array(ref mut values) = *self {
1292            values.push(value);
1293        }
1294    }
1295
1296    /// A convenience method to extract a field out of an [Object](#variant.Object).
1297    /// Returns `None` for other value kinds or if the field isn't present.
1298    pub fn get(&self, name: &str) -> Option<&Value<'a>> {
1299        match *self {
1300            Value::Object(_, ref fields) => fields.get(name),
1301            _ => None,
1302        }
1303    }
1304
1305    /// A convenience method to update a field on an [Object](#variant.Object).
1306    /// Does nothing for other value kinds.
1307    pub fn set(&mut self, name: &'a str, value: Value<'a>) {
1308        if let Value::Object(_, ref mut fields) = *self {
1309            fields.insert(name, value);
1310        }
1311    }
1312
1313    /// A convenience method to remove a field on an [Object](#variant.Object).
1314    /// Does nothing for other value kinds.
1315    pub fn remove(&mut self, name: &'a str) {
1316        if let Value::Object(_, ref mut fields) = *self {
1317            fields.remove(name);
1318        }
1319    }
1320
1321    /// Decodes the type specified by `type_id` and `schema` from `bytes`.
1322    pub fn decode(schema: &'a Schema, type_id: i32, bytes: &[u8]) -> Result<Value<'a>, ()> {
1323        Value::decode_bb(schema, type_id, &mut ByteBuffer::new(bytes))
1324    }
1325
1326    /// Encodes this value into an array of bytes using the provided `schema`.
1327    pub fn encode(&self, schema: &Schema) -> Vec<u8> {
1328        let mut bb = ByteBufferMut::new();
1329        self.encode_bb(schema, &mut bb);
1330        bb.data()
1331    }
1332
1333    /// Decodes the type specified by `type_id` and `schema` from `bb` starting
1334    /// at the current index. After this function returns, the current index will
1335    /// be advanced by the amount of data that was successfully parsed. This is
1336    /// mainly useful as a helper routine for [decode](#method.decode), which you
1337    /// probably want to use instead.
1338    pub fn decode_bb(
1339        schema: &'a Schema,
1340        type_id: i32,
1341        bb: &mut ByteBuffer,
1342    ) -> Result<Value<'a>, ()> {
1343        match type_id {
1344            TYPE_BOOL => Ok(Value::Bool(bb.read_bool()?)),
1345            TYPE_BYTE => Ok(Value::Byte(bb.read_byte()?)),
1346            TYPE_INT => Ok(Value::Int(bb.read_var_int()?)),
1347            TYPE_UINT => Ok(Value::UInt(bb.read_var_uint()?)),
1348            TYPE_FLOAT => Ok(Value::Float(bb.read_var_float()?)),
1349            TYPE_STRING => Ok(Value::String(bb.read_string()?.into_owned())),
1350            TYPE_INT64 => Ok(Value::Int64(bb.read_var_int64()?)),
1351            TYPE_UINT64 => Ok(Value::UInt64(bb.read_var_uint64()?)),
1352
1353            _ => {
1354                let def = &schema.defs[type_id as usize];
1355
1356                match def.kind {
1357                    DefKind::Enum => {
1358                        if let Some(index) = def.field_value_to_index.get(&bb.read_var_uint()?) {
1359                            Ok(Value::Enum(
1360                                def.name.as_str(),
1361                                def.fields[*index].name.as_str(),
1362                            ))
1363                        } else {
1364                            Err(())
1365                        }
1366                    }
1367
1368                    DefKind::Struct => {
1369                        let mut fields = HashMap::new();
1370                        for field in &def.fields {
1371                            fields.insert(
1372                                field.name.as_str(),
1373                                Value::decode_field_bb(schema, field, bb)?,
1374                            );
1375                        }
1376                        Ok(Value::Object(def.name.as_str(), fields))
1377                    }
1378
1379                    DefKind::Message => {
1380                        let mut fields = HashMap::new();
1381                        loop {
1382                            let value = bb.read_var_uint()?;
1383                            if value == 0 {
1384                                return Ok(Value::Object(def.name.as_str(), fields));
1385                            }
1386                            if let Some(index) = def.field_value_to_index.get(&value) {
1387                                let field = &def.fields[*index];
1388                                fields.insert(
1389                                    field.name.as_str(),
1390                                    Value::decode_field_bb(schema, field, bb)?,
1391                                );
1392                            } else {
1393                                return Err(());
1394                            }
1395                        }
1396                    }
1397                }
1398            }
1399        }
1400    }
1401
1402    /// Decodes the field specified by `field` and `schema` from `bb` starting
1403    /// at the current index. This is used by [decode_bb](#method.decode_bb) but
1404    /// may also be useful by itself.
1405    pub fn decode_field_bb(
1406        schema: &'a Schema,
1407        field: &Field,
1408        bb: &mut ByteBuffer,
1409    ) -> Result<Value<'a>, ()> {
1410        if field.is_array {
1411            let len = bb.read_var_uint()? as usize;
1412            let mut array = Vec::with_capacity(len);
1413            for _ in 0..len {
1414                array.push(Value::decode_bb(schema, field.type_id, bb)?);
1415            }
1416            Ok(Value::Array(array))
1417        } else {
1418            Value::decode_bb(schema, field.type_id, bb)
1419        }
1420    }
1421
1422    /// Encodes the current value to the end of `bb` using the provided `schema`.
1423    /// This is mainly useful as a helper routine for [encode](#method.encode),
1424    /// which you probably want to use instead.
1425    pub fn encode_bb(&self, schema: &Schema, bb: &mut ByteBufferMut) {
1426        match *self {
1427            Value::Bool(value) => bb.write_byte(if value { 1 } else { 0 }),
1428            Value::Byte(value) => bb.write_byte(value),
1429            Value::Int(value) => bb.write_var_int(value),
1430            Value::UInt(value) => bb.write_var_uint(value),
1431            Value::Float(value) => bb.write_var_float(value),
1432            Value::String(ref value) => bb.write_string(value.as_str()),
1433            Value::Int64(value) => bb.write_var_int64(value),
1434            Value::UInt64(value) => bb.write_var_uint64(value),
1435
1436            Value::Array(ref values) => {
1437                bb.write_var_uint(values.len() as u32);
1438                for value in values {
1439                    value.encode_bb(schema, bb);
1440                }
1441                return;
1442            }
1443
1444            Value::Enum(name, value) => {
1445                let def = &schema.defs[*schema.def_name_to_index.get(name).unwrap()];
1446                let index = *def.field_name_to_index.get(value).unwrap();
1447                bb.write_var_uint(def.fields[index].value);
1448            }
1449
1450            Value::Object(name, ref fields) => {
1451                let def = &schema.defs[*schema.def_name_to_index.get(name).unwrap()];
1452                match def.kind {
1453                    DefKind::Enum => panic!(),
1454                    DefKind::Struct => {
1455                        for field in &def.fields {
1456                            fields
1457                                .get(field.name.as_str())
1458                                .unwrap()
1459                                .encode_bb(schema, bb);
1460                        }
1461                    }
1462                    DefKind::Message => {
1463                        // Loop over all fields to ensure consistent encoding order
1464                        for field in &def.fields {
1465                            if let Some(value) = fields.get(field.name.as_str()) {
1466                                bb.write_var_uint(field.value);
1467                                value.encode_bb(schema, bb);
1468                            }
1469                        }
1470                        bb.write_byte(0);
1471                    }
1472                }
1473            }
1474        }
1475    }
1476}
1477
1478impl<'a> Index<usize> for Value<'a> {
1479    type Output = Value<'a>;
1480
1481    /// A convenience method that adds support for `self[index]` expressions.
1482    /// It will panic if this value isn't an [Array](#variant.Array) or if the
1483    /// provided index is out of bounds.
1484    fn index(&self, index: usize) -> &Value<'a> {
1485        match *self {
1486            Value::Array(ref values) => &values[index],
1487            _ => panic!(),
1488        }
1489    }
1490}
1491
1492impl<'a> fmt::Debug for Value<'a> {
1493    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1494        match *self {
1495            Value::Bool(value) => value.fmt(f),
1496            Value::Byte(value) => value.fmt(f),
1497            Value::Int(value) => value.fmt(f),
1498            Value::UInt(value) => value.fmt(f),
1499            Value::Float(value) => value.fmt(f),
1500            Value::String(ref value) => value.fmt(f),
1501            Value::Int64(value) => value.fmt(f),
1502            Value::UInt64(value) => value.fmt(f),
1503            Value::Array(ref values) => values.fmt(f),
1504            Value::Enum(name, ref value) => write!(f, "{}::{}", name, value),
1505
1506            Value::Object(name, ref fields) => {
1507                let mut keys: Vec<_> = fields.keys().collect();
1508                let mut first = true;
1509                keys.sort();
1510                write!(f, "{} {{", name)?;
1511
1512                for key in keys {
1513                    if first {
1514                        first = false;
1515                    } else {
1516                        write!(f, ", ")?;
1517                    }
1518                    write!(f, "{}: {:?}", key, fields[key])?;
1519                }
1520
1521                write!(f, "}}")
1522            }
1523        }
1524    }
1525}
1526
1527#[test]
1528fn value_basic() {
1529    let value = Value::Array(vec![
1530        Value::Bool(true),
1531        Value::Byte(255),
1532        Value::Int(-1),
1533        Value::UInt(1),
1534        Value::Float(0.5),
1535        Value::String("abc".to_owned()),
1536        Value::Enum("Foo", "FOO"),
1537        Value::Object("Obj", {
1538            let mut map = HashMap::new();
1539            map.insert("key1", Value::String("value1".to_owned()));
1540            map.insert("key2", Value::String("value2".to_owned()));
1541            map
1542        }),
1543    ]);
1544
1545    assert_eq!(value.len(), 8);
1546
1547    assert_eq!(value[0], Value::Bool(true));
1548    assert_eq!(value[1], Value::Byte(255));
1549    assert_eq!(value[2], Value::Int(-1));
1550    assert_eq!(value[3], Value::UInt(1));
1551    assert_eq!(value[4], Value::Float(0.5));
1552    assert_eq!(value[5], Value::String("abc".to_owned()));
1553    assert_eq!(value[6], Value::Enum("Foo", "FOO"));
1554    assert_eq!(
1555        value[7],
1556        Value::Object("Obj", {
1557            let mut map = HashMap::new();
1558            map.insert("key1", Value::String("value1".to_owned()));
1559            map.insert("key2", Value::String("value2".to_owned()));
1560            map
1561        })
1562    );
1563
1564    assert_eq!(value[0].as_bool(), true);
1565    assert_eq!(value[1].as_byte(), 255);
1566    assert_eq!(value[2].as_int(), -1);
1567    assert_eq!(value[3].as_uint(), 1);
1568    assert_eq!(value[4].as_float(), 0.5);
1569    assert_eq!(value[5].as_string(), "abc");
1570    assert_eq!(value.get("key1"), None);
1571    assert_eq!(
1572        value[7].get("key1"),
1573        Some(&Value::String("value1".to_owned()))
1574    );
1575
1576    assert_eq!(
1577        format!("{:?}", value),
1578        "[true, 255, -1, 1, 0.5, \"abc\", Foo::FOO, Obj {key1: \"value1\", key2: \"value2\"}]"
1579    );
1580}
1581
1582#[test]
1583fn value_push() {
1584    let mut value = Value::Array(vec![]);
1585    assert_eq!(value.len(), 0);
1586
1587    value.push(Value::Int(123));
1588    assert_eq!(value.len(), 1);
1589    assert_eq!(value[0], Value::Int(123));
1590
1591    value.push(Value::Int(456));
1592    assert_eq!(value.len(), 2);
1593    assert_eq!(value[0], Value::Int(123));
1594    assert_eq!(value[1], Value::Int(456));
1595}
1596
1597#[test]
1598fn value_set() {
1599    let mut value = Value::Object("Foo", HashMap::new());
1600    assert_eq!(value.get("x"), None);
1601
1602    value.set("x", Value::Int(123));
1603    assert_eq!(value.get("x"), Some(&Value::Int(123)));
1604
1605    value.set("y", Value::Int(456));
1606    assert_eq!(value.get("x"), Some(&Value::Int(123)));
1607    assert_eq!(value.get("y"), Some(&Value::Int(456)));
1608
1609    value.set("x", Value::Int(789));
1610    assert_eq!(value.get("x"), Some(&Value::Int(789)));
1611    assert_eq!(value.get("y"), Some(&Value::Int(456)));
1612}
1613
1614#[test]
1615fn value_remove() {
1616    let mut value = Value::Object("Foo", HashMap::new());
1617    assert_eq!(value.get("x"), None);
1618
1619    value.set("x", Value::Int(123));
1620    assert_eq!(value.get("x"), Some(&Value::Int(123)));
1621
1622    value.set("y", Value::Int(456));
1623    assert_eq!(value.get("x"), Some(&Value::Int(123)));
1624    assert_eq!(value.get("y"), Some(&Value::Int(456)));
1625
1626    value.remove("x");
1627    assert_eq!(value.get("x"), None);
1628    assert_eq!(value.get("y"), Some(&Value::Int(456)));
1629
1630    value.remove("y");
1631    assert_eq!(value.get("x"), None);
1632    assert_eq!(value.get("y"), None);
1633}
1634
1635#[test]
1636fn value_encode_and_decode() {
1637    let schema = Schema::new(vec![
1638        Def::new(
1639            "Enum".to_owned(),
1640            DefKind::Enum,
1641            vec![
1642                Field {
1643                    name: "FOO".to_owned(),
1644                    type_id: 0,
1645                    is_array: false,
1646                    value: 100,
1647                },
1648                Field {
1649                    name: "BAR".to_owned(),
1650                    type_id: 0,
1651                    is_array: false,
1652                    value: 200,
1653                },
1654            ],
1655        ),
1656        Def::new(
1657            "Struct".to_owned(),
1658            DefKind::Struct,
1659            vec![
1660                Field {
1661                    name: "v_enum".to_owned(),
1662                    type_id: 0,
1663                    is_array: true,
1664                    value: 0,
1665                },
1666                Field {
1667                    name: "v_message".to_owned(),
1668                    type_id: 2,
1669                    is_array: false,
1670                    value: 0,
1671                },
1672            ],
1673        ),
1674        Def::new(
1675            "Message".to_owned(),
1676            DefKind::Message,
1677            vec![
1678                Field {
1679                    name: "v_bool".to_owned(),
1680                    type_id: TYPE_BOOL,
1681                    is_array: false,
1682                    value: 1,
1683                },
1684                Field {
1685                    name: "v_byte".to_owned(),
1686                    type_id: TYPE_BYTE,
1687                    is_array: false,
1688                    value: 2,
1689                },
1690                Field {
1691                    name: "v_int".to_owned(),
1692                    type_id: TYPE_INT,
1693                    is_array: false,
1694                    value: 3,
1695                },
1696                Field {
1697                    name: "v_uint".to_owned(),
1698                    type_id: TYPE_UINT,
1699                    is_array: false,
1700                    value: 4,
1701                },
1702                Field {
1703                    name: "v_float".to_owned(),
1704                    type_id: TYPE_FLOAT,
1705                    is_array: false,
1706                    value: 5,
1707                },
1708                Field {
1709                    name: "v_string".to_owned(),
1710                    type_id: TYPE_STRING,
1711                    is_array: false,
1712                    value: 6,
1713                },
1714                Field {
1715                    name: "v_int64".to_owned(),
1716                    type_id: TYPE_INT64,
1717                    is_array: false,
1718                    value: 7,
1719                },
1720                Field {
1721                    name: "v_uint64".to_owned(),
1722                    type_id: TYPE_UINT64,
1723                    is_array: false,
1724                    value: 8,
1725                },
1726                Field {
1727                    name: "v_enum".to_owned(),
1728                    type_id: 0,
1729                    is_array: false,
1730                    value: 9,
1731                },
1732                Field {
1733                    name: "v_struct".to_owned(),
1734                    type_id: 1,
1735                    is_array: false,
1736                    value: 10,
1737                },
1738                Field {
1739                    name: "v_message".to_owned(),
1740                    type_id: 2,
1741                    is_array: false,
1742                    value: 11,
1743                },
1744                Field {
1745                    name: "a_bool".to_owned(),
1746                    type_id: TYPE_BOOL,
1747                    is_array: true,
1748                    value: 12,
1749                },
1750                Field {
1751                    name: "a_byte".to_owned(),
1752                    type_id: TYPE_BYTE,
1753                    is_array: true,
1754                    value: 13,
1755                },
1756                Field {
1757                    name: "a_int".to_owned(),
1758                    type_id: TYPE_INT,
1759                    is_array: true,
1760                    value: 14,
1761                },
1762                Field {
1763                    name: "a_uint".to_owned(),
1764                    type_id: TYPE_UINT,
1765                    is_array: true,
1766                    value: 15,
1767                },
1768                Field {
1769                    name: "a_float".to_owned(),
1770                    type_id: TYPE_FLOAT,
1771                    is_array: true,
1772                    value: 16,
1773                },
1774                Field {
1775                    name: "a_string".to_owned(),
1776                    type_id: TYPE_STRING,
1777                    is_array: true,
1778                    value: 17,
1779                },
1780                Field {
1781                    name: "a_int64".to_owned(),
1782                    type_id: TYPE_INT64,
1783                    is_array: true,
1784                    value: 18,
1785                },
1786                Field {
1787                    name: "a_uint64".to_owned(),
1788                    type_id: TYPE_UINT64,
1789                    is_array: true,
1790                    value: 19,
1791                },
1792                Field {
1793                    name: "a_enum".to_owned(),
1794                    type_id: 0,
1795                    is_array: true,
1796                    value: 20,
1797                },
1798                Field {
1799                    name: "a_struct".to_owned(),
1800                    type_id: 1,
1801                    is_array: true,
1802                    value: 21,
1803                },
1804                Field {
1805                    name: "a_message".to_owned(),
1806                    type_id: 2,
1807                    is_array: true,
1808                    value: 22,
1809                },
1810            ],
1811        ),
1812    ]);
1813
1814    assert!(Schema::decode(&schema.encode()).is_ok());
1815
1816    assert_eq!(
1817        Value::decode(&schema, TYPE_BOOL, &[0]),
1818        Ok(Value::Bool(false))
1819    );
1820    assert_eq!(
1821        Value::decode(&schema, TYPE_BOOL, &[1]),
1822        Ok(Value::Bool(true))
1823    );
1824    assert_eq!(Value::decode(&schema, TYPE_BOOL, &[2]), Err(()));
1825    assert_eq!(
1826        Value::decode(&schema, TYPE_BYTE, &[255]),
1827        Ok(Value::Byte(255))
1828    );
1829    assert_eq!(Value::decode(&schema, TYPE_INT, &[1]), Ok(Value::Int(-1)));
1830    assert_eq!(Value::decode(&schema, TYPE_UINT, &[1]), Ok(Value::UInt(1)));
1831    assert_eq!(
1832        Value::decode(&schema, TYPE_FLOAT, &[126, 0, 0, 0]),
1833        Ok(Value::Float(0.5))
1834    );
1835    assert_eq!(
1836        Value::decode(&schema, TYPE_STRING, &[240, 159, 141, 149, 0]),
1837        Ok(Value::String("🍕".to_owned()))
1838    );
1839    assert_eq!(
1840        Value::decode(&schema, TYPE_INT64, &[1]),
1841        Ok(Value::Int64(-1))
1842    );
1843    assert_eq!(
1844        Value::decode(&schema, TYPE_UINT64, &[1]),
1845        Ok(Value::UInt64(1))
1846    );
1847    assert_eq!(Value::decode(&schema, 0, &[0]), Err(()));
1848    assert_eq!(
1849        Value::decode(&schema, 0, &[100]),
1850        Ok(Value::Enum("Enum", "FOO"))
1851    );
1852    assert_eq!(
1853        Value::decode(&schema, 0, &[200, 1]),
1854        Ok(Value::Enum("Enum", "BAR"))
1855    );
1856
1857    assert_eq!(Value::Bool(false).encode(&schema), [0]);
1858    assert_eq!(Value::Bool(true).encode(&schema), [1]);
1859    assert_eq!(Value::Byte(255).encode(&schema), [255]);
1860    assert_eq!(Value::Int(-1).encode(&schema), [1]);
1861    assert_eq!(Value::UInt(1).encode(&schema), [1]);
1862    assert_eq!(Value::Float(0.5).encode(&schema), [126, 0, 0, 0]);
1863    assert_eq!(
1864        Value::String("🍕".to_owned()).encode(&schema),
1865        [240, 159, 141, 149, 0]
1866    );
1867    assert_eq!(Value::Int64(-1).encode(&schema), [1]);
1868    assert_eq!(Value::UInt64(1).encode(&schema), [1]);
1869    assert_eq!(Value::Enum("Enum", "FOO").encode(&schema), [100]);
1870    assert_eq!(Value::Enum("Enum", "BAR").encode(&schema), [200, 1]);
1871
1872    fn insert<'a>(
1873        mut map: HashMap<&'a str, Value<'a>>,
1874        key: &'a str,
1875        value: Value<'a>,
1876    ) -> HashMap<&'a str, Value<'a>> {
1877        map.insert(key, value);
1878        map
1879    }
1880
1881    let empty_struct = Value::Object(
1882        "Struct",
1883        insert(
1884            insert(HashMap::new(), "v_enum", Value::Array(vec![])),
1885            "v_message",
1886            Value::Object("Message", HashMap::new()),
1887        ),
1888    );
1889
1890    assert_eq!(Value::decode(&schema, 1, &[0, 0]), Ok(empty_struct.clone()));
1891    assert_eq!(empty_struct.encode(&schema), [0, 0]);
1892
1893    let full_struct = Value::Object(
1894        "Struct",
1895        insert(
1896            insert(
1897                HashMap::new(),
1898                "v_enum",
1899                Value::Array(vec![Value::Enum("Enum", "FOO"), Value::Enum("Enum", "BAR")]),
1900            ),
1901            "v_message",
1902            Value::Object(
1903                "Message",
1904                insert(HashMap::new(), "v_string", Value::String("🍕".to_owned())),
1905            ),
1906        ),
1907    );
1908
1909    assert_eq!(
1910        Value::decode(&schema, 1, &[2, 100, 200, 1, 6, 240, 159, 141, 149, 0, 0]),
1911        Ok(full_struct.clone())
1912    );
1913    assert_eq!(
1914        full_struct.encode(&schema),
1915        [2, 100, 200, 1, 6, 240, 159, 141, 149, 0, 0]
1916    );
1917
1918    assert_eq!(
1919        Value::Object(
1920            "Message",
1921            insert(HashMap::new(), "v_bool", Value::Bool(false))
1922        )
1923        .encode(&schema),
1924        [1, 0, 0]
1925    );
1926    assert_eq!(
1927        Value::Object(
1928            "Message",
1929            insert(HashMap::new(), "v_bool", Value::Bool(true))
1930        )
1931        .encode(&schema),
1932        [1, 1, 0]
1933    );
1934    assert_eq!(
1935        Value::Object(
1936            "Message",
1937            insert(HashMap::new(), "v_byte", Value::Byte(255))
1938        )
1939        .encode(&schema),
1940        [2, 255, 0]
1941    );
1942    assert_eq!(
1943        Value::Object("Message", insert(HashMap::new(), "v_int", Value::Int(-1))).encode(&schema),
1944        [3, 1, 0]
1945    );
1946    assert_eq!(
1947        Value::Object("Message", insert(HashMap::new(), "v_uint", Value::UInt(1))).encode(&schema),
1948        [4, 1, 0]
1949    );
1950    assert_eq!(
1951        Value::Object(
1952            "Message",
1953            insert(HashMap::new(), "v_float", Value::Float(0.0))
1954        )
1955        .encode(&schema),
1956        [5, 0, 0]
1957    );
1958    assert_eq!(
1959        Value::Object(
1960            "Message",
1961            insert(HashMap::new(), "v_string", Value::String("".to_owned()))
1962        )
1963        .encode(&schema),
1964        [6, 0, 0]
1965    );
1966    assert_eq!(
1967        Value::Object("Message", insert(HashMap::new(), "v_int64", Value::Int(-1))).encode(&schema),
1968        [7, 1, 0]
1969    );
1970    assert_eq!(
1971        Value::Object(
1972            "Message",
1973            insert(HashMap::new(), "v_uint64", Value::UInt(1))
1974        )
1975        .encode(&schema),
1976        [8, 1, 0]
1977    );
1978    assert_eq!(
1979        Value::Object(
1980            "Message",
1981            insert(HashMap::new(), "v_enum", Value::Enum("Enum", "FOO"))
1982        )
1983        .encode(&schema),
1984        [9, 100, 0]
1985    );
1986    assert_eq!(
1987        Value::Object(
1988            "Message",
1989            insert(HashMap::new(), "v_struct", empty_struct.clone())
1990        )
1991        .encode(&schema),
1992        [10, 0, 0, 0]
1993    );
1994    assert_eq!(
1995        Value::Object(
1996            "Message",
1997            insert(
1998                HashMap::new(),
1999                "v_message",
2000                Value::Object("Message", HashMap::new())
2001            )
2002        )
2003        .encode(&schema),
2004        [11, 0, 0]
2005    );
2006
2007    assert_eq!(
2008        Value::decode(&schema, 2, &[1, 0, 0]),
2009        Ok(Value::Object(
2010            "Message",
2011            insert(HashMap::new(), "v_bool", Value::Bool(false))
2012        ))
2013    );
2014    assert_eq!(
2015        Value::decode(&schema, 2, &[1, 1, 0]),
2016        Ok(Value::Object(
2017            "Message",
2018            insert(HashMap::new(), "v_bool", Value::Bool(true))
2019        ))
2020    );
2021    assert_eq!(
2022        Value::decode(&schema, 2, &[2, 255, 0]),
2023        Ok(Value::Object(
2024            "Message",
2025            insert(HashMap::new(), "v_byte", Value::Byte(255))
2026        ))
2027    );
2028    assert_eq!(
2029        Value::decode(&schema, 2, &[3, 1, 0]),
2030        Ok(Value::Object(
2031            "Message",
2032            insert(HashMap::new(), "v_int", Value::Int(-1))
2033        ))
2034    );
2035    assert_eq!(
2036        Value::decode(&schema, 2, &[4, 1, 0]),
2037        Ok(Value::Object(
2038            "Message",
2039            insert(HashMap::new(), "v_uint", Value::UInt(1))
2040        ))
2041    );
2042    assert_eq!(
2043        Value::decode(&schema, 2, &[5, 0, 0]),
2044        Ok(Value::Object(
2045            "Message",
2046            insert(HashMap::new(), "v_float", Value::Float(0.0))
2047        ))
2048    );
2049    assert_eq!(
2050        Value::decode(&schema, 2, &[6, 0, 0]),
2051        Ok(Value::Object(
2052            "Message",
2053            insert(HashMap::new(), "v_string", Value::String("".to_owned()))
2054        ))
2055    );
2056    assert_eq!(
2057        Value::decode(&schema, 2, &[7, 1, 0]),
2058        Ok(Value::Object(
2059            "Message",
2060            insert(HashMap::new(), "v_int64", Value::Int64(-1))
2061        ))
2062    );
2063    assert_eq!(
2064        Value::decode(&schema, 2, &[8, 1, 0]),
2065        Ok(Value::Object(
2066            "Message",
2067            insert(HashMap::new(), "v_uint64", Value::UInt64(1))
2068        ))
2069    );
2070    assert_eq!(
2071        Value::decode(&schema, 2, &[9, 100, 0]),
2072        Ok(Value::Object(
2073            "Message",
2074            insert(HashMap::new(), "v_enum", Value::Enum("Enum", "FOO"))
2075        ))
2076    );
2077    assert_eq!(
2078        Value::decode(&schema, 2, &[10, 0, 0, 0]),
2079        Ok(Value::Object(
2080            "Message",
2081            insert(HashMap::new(), "v_struct", empty_struct.clone())
2082        ))
2083    );
2084    assert_eq!(
2085        Value::decode(&schema, 2, &[11, 0, 0]),
2086        Ok(Value::Object(
2087            "Message",
2088            insert(
2089                HashMap::new(),
2090                "v_message",
2091                Value::Object("Message", HashMap::new())
2092            )
2093        ))
2094    );
2095}
2096
2097// This test case is for a bug where rustc was silently inferring an incorrect
2098// lifetime. This is the specific error:
2099//
2100//   error[E0597]: `value` does not live long enough
2101//       --> src/lib.rs:1307:40
2102//        |
2103//   1307 |     if let Some(Value::Array(items)) = value.get("items") {
2104//        |                                        ^^^^^ borrowed value does not live long enough
2105//   ...
2106//   1312 |   }
2107//        |   - borrowed value only lives until here
2108//        |
2109//        = note: borrowed value must be valid for the static lifetime...
2110//
2111// The fix was to change this:
2112//
2113//   pub fn get(&self, name: &str) -> Option<&Value> {
2114//
2115// Into this:
2116//
2117//   pub fn get(&self, name: &str) -> Option<&Value<'a>> {
2118//
2119#[test]
2120fn value_get_bad_lifetime_inference_in_rustc() {
2121    fn use_item<'a>(_: &'a Value<'static>) {}
2122
2123    fn use_items(value: Value<'static>) {
2124        if let Some(Value::Array(items)) = value.get("items") {
2125            for item in items {
2126                use_item(item);
2127            }
2128        }
2129    }
2130
2131    use_items(Value::Array(vec![]));
2132}