Skip to main content

chive/
lib.rs

1#[cfg(test)]
2mod test;
3
4use std::{fs, io, marker::PhantomData, path::Path};
5
6/// Trait for a user-defined type that can be serialized and deserialized
7/// into a Chive.
8pub trait Chivable: Sized {
9    /// Serialize self into the ChiveIn by adding all
10    /// relevant members in a stable order
11    fn chive_in(&self, chive_in: &mut ChiveIn);
12
13    /// Create a new instance of Self by deserializing
14    /// all relevant members in the same order they were
15    /// serialized by Self::chive_in()
16    fn chive_out(chive_out: &mut ChiveOut) -> Result<Self, ()>;
17}
18
19/// Default implementation for the unit type
20impl Chivable for () {
21    fn chive_in(&self, _chive_in: &mut ChiveIn) {
22        // Nothing to do
23    }
24
25    fn chive_out(_chive_out: &mut ChiveOut) -> Result<Self, ()> {
26        Ok(())
27    }
28}
29
30/// Enum for the set of primitive fixed-size types that are supported
31#[derive(PartialEq, Eq, Debug)]
32pub enum PrimitiveType {
33    Bool,
34    U8,
35    I8,
36    U16,
37    I16,
38    U32,
39    I32,
40    U64,
41    I64,
42    F32,
43    F64,
44}
45
46/// Enum for set the of value types that are supported
47#[derive(PartialEq, Eq, Debug)]
48pub enum ValueType {
49    /// A fixed-size primitive, e.g. boolean, integer, or floating point number
50    Primitive(PrimitiveType),
51
52    /// A list of values of a common primitive type whose number of elements can be queried
53    Array(PrimitiveType),
54
55    /// A utf-8 encoded string
56    String,
57
58    /// A chive within. Useful for encapsulating and separating sections of the chive
59    /// for different purposes.
60    Nest,
61}
62
63impl PrimitiveType {
64    /// Returns an integer with value 0xF or less, used to uniquely tag each primitive type
65    fn to_nibble(&self) -> u8 {
66        match self {
67            PrimitiveType::Bool => 0x01,
68            PrimitiveType::U8 => 0x02,
69            PrimitiveType::I8 => 0x03,
70            PrimitiveType::U16 => 0x04,
71            PrimitiveType::I16 => 0x05,
72            PrimitiveType::U32 => 0x06,
73            PrimitiveType::I32 => 0x07,
74            PrimitiveType::U64 => 0x08,
75            PrimitiveType::I64 => 0x09,
76            PrimitiveType::F32 => 0x0A,
77            PrimitiveType::F64 => 0x0B,
78        }
79    }
80
81    /// Constructs a PrimitiveType from an integer value as returned by to_nibble()
82    fn from_nibble(byte: u8) -> Result<PrimitiveType, ()> {
83        match byte {
84            0x01 => Ok(PrimitiveType::Bool),
85            0x02 => Ok(PrimitiveType::U8),
86            0x03 => Ok(PrimitiveType::I8),
87            0x04 => Ok(PrimitiveType::U16),
88            0x05 => Ok(PrimitiveType::I16),
89            0x06 => Ok(PrimitiveType::U32),
90            0x07 => Ok(PrimitiveType::I32),
91            0x08 => Ok(PrimitiveType::U64),
92            0x09 => Ok(PrimitiveType::I64),
93            0x0A => Ok(PrimitiveType::F32),
94            0x0B => Ok(PrimitiveType::F64),
95            _ => Err(()),
96        }
97    }
98}
99
100impl ValueType {
101    /// Returns an integer used to uniquely tag each value type
102    fn to_byte(&self) -> u8 {
103        match self {
104            ValueType::Primitive(prim_type) => 0x00 | prim_type.to_nibble(),
105            ValueType::Array(prim_type) => 0x10 | prim_type.to_nibble(),
106            ValueType::String => 0x20,
107            ValueType::Nest => 0x30,
108        }
109    }
110
111    /// Constructs a ValueType from an integer value as returned by to_byte()
112    fn from_byte(byte: u8) -> Result<ValueType, ()> {
113        let hi_nibble = byte & 0xF0;
114        let lo_nibble = byte & 0x0F;
115        match hi_nibble {
116            0x00 => Ok(ValueType::Primitive(PrimitiveType::from_nibble(lo_nibble)?)),
117            0x10 => Ok(ValueType::Array(PrimitiveType::from_nibble(lo_nibble)?)),
118            0x20 => Ok(ValueType::String),
119            0x30 => Ok(ValueType::Nest),
120            _ => Err(()),
121        }
122    }
123}
124
125/// Helper trait for serializing primitives directly
126trait PrimitiveReadWrite {
127    /// The number of bytes occupied by the value itself in memory
128    const SIZE: usize;
129
130    /// The PrimitiveType that this type corresponds to, e.g. PrimitiveType::I32 for i32
131    const TYPE: PrimitiveType;
132
133    /// Write self to the byte vector
134    fn write_to(&self, data: &mut Vec<u8>);
135
136    /// Read self from the byte vector.
137    /// This method may panic if there are fewer than Self::SIZE bytes in the vector.
138    fn read_from(data: &mut ChiveOut) -> Self;
139}
140
141/// Macro for implementing the PrimitiveReadWrite helper trait for a given
142/// Rust type, given its size in bytes and its corresponding PrimitiveType.
143/// The methods `to_be_bytes()` and `from_be_bytes` are used, which exist
144/// for all primitive integer and floating point types
145macro_rules! impl_primitive_read_write {
146    ($primitive: ident, $size: literal, $typetag: expr) => {
147        impl PrimitiveReadWrite for $primitive {
148            const SIZE: usize = $size;
149            const TYPE: PrimitiveType = $typetag;
150            fn write_to(&self, data: &mut Vec<u8>) {
151                for b in self.to_be_bytes() {
152                    data.push(b);
153                }
154            }
155            fn read_from(d: &mut ChiveOut) -> Self {
156                let mut bytes = Self::default().to_be_bytes();
157                for b in &mut bytes {
158                    *b = d.read_byte().unwrap();
159                }
160                Self::from_be_bytes(bytes)
161            }
162        }
163    };
164}
165
166impl_primitive_read_write!(u8, 1, PrimitiveType::U8);
167impl_primitive_read_write!(i8, 1, PrimitiveType::I8);
168impl_primitive_read_write!(u16, 2, PrimitiveType::U16);
169impl_primitive_read_write!(i16, 2, PrimitiveType::I16);
170impl_primitive_read_write!(u32, 4, PrimitiveType::U32);
171impl_primitive_read_write!(i32, 4, PrimitiveType::I32);
172impl_primitive_read_write!(u64, 8, PrimitiveType::U64);
173impl_primitive_read_write!(i64, 8, PrimitiveType::I64);
174impl_primitive_read_write!(f32, 4, PrimitiveType::F32);
175impl_primitive_read_write!(f64, 8, PrimitiveType::F64);
176
177/// Explicit implementation of PrimitiveReadWrite for bool,
178/// which does not have from_be_bytes() / to_be_bytes()
179impl PrimitiveReadWrite for bool {
180    const SIZE: usize = 1;
181    const TYPE: PrimitiveType = PrimitiveType::Bool;
182
183    fn write_to(&self, data: &mut Vec<u8>) {
184        data.push(if *self { 1 } else { 0 });
185    }
186
187    fn read_from(d: &mut ChiveOut) -> bool {
188        d.read_byte().unwrap() != 0
189    }
190}
191
192/// An in-memory archive of serialized data, which is simply a flat sequence
193/// of bytes that can be saved, sent, copied, loaded, and deserialized again
194/// at a different time and place.
195///
196/// To serialize data structures, use the [Chive::with_chive_in] method and
197/// then use the given [ChiveIn] object to write individual values and objects.
198///
199/// To deserialize data structures, use the [Chive::chive_out] method and then
200/// use the returned [ChiveOut] object to read data in the same order it was
201/// written during serialization.
202pub struct Chive {
203    /// The serialized data. This may have been loaded from an arbitrary file
204    /// or created from an arbitrary vector, and so may not have a valid structure.
205    /// Validation is performed during deserialization using a Result<> return
206    /// type on each deserialization method.
207    data: Vec<u8>,
208}
209
210/// Public methods
211impl Chive {
212    /// Create a new Chive instance by serializing data a user-provided function
213    /// that receives a [ChiveIn] instance. The body of the function needs to
214    /// write all relevant data to the [ChiveIn] object. It is (currently) not
215    /// possible to write additional data afterwards.
216    ///
217    /// Returns a Chive instance containing a flattened representation of all
218    /// data that was given to the [ChiveIn] object.
219    pub fn with_chive_in<F: Fn(ChiveIn)>(f: F) -> Chive {
220        let mut data = Vec::<u8>::new();
221
222        data.push(0);
223        data.push(0);
224        data.push(0);
225        data.push(0);
226
227        let chive_in = ChiveIn::new(&mut data);
228        f(chive_in);
229
230        debug_assert!(data.len() >= 4);
231        let len_bytes = (data.len() - 4) as u32;
232        let [b0, b1, b2, b3] = len_bytes.to_be_bytes();
233
234        data[0] = b0;
235        data[1] = b1;
236        data[2] = b2;
237        data[3] = b3;
238
239        Chive { data }
240    }
241
242    /// Get a [ChiveOut] instance to deserialize and retrieve individual values
243    /// out of the raw binary data.
244    pub fn chive_out<'a>(&'a self) -> Result<ChiveOut<'a>, ()> {
245        if self.data.len() < 4 {
246            return Err(());
247        }
248        let len =
249            u32::from_be_bytes([self.data[0], self.data[1], self.data[2], self.data[3]]) as usize;
250        let slice = &self.data[4..];
251        if len != slice.len() {
252            return Err(());
253        }
254        Ok(ChiveOut {
255            data: slice,
256            position: 0,
257        })
258    }
259
260    /// Write the binary contents the chive to a file at the given path
261    pub fn dump_to_file(&self, path: &Path) -> Result<(), io::Error> {
262        // TODO: magic number?
263        fs::write(path, &self.data)?;
264        Ok(())
265    }
266
267    /// Read the file at the given path and load its binary data into
268    /// a new Chive instance. No validation of the contents is performed.
269    pub fn load_from_file(path: &Path) -> Result<Chive, io::Error> {
270        // TODO: magic number?
271        let data = fs::read(path)?;
272        Ok(Chive { data })
273    }
274
275    /// Take the underlying vector of bytes
276    pub fn into_vec(self) -> Vec<u8> {
277        self.data
278    }
279
280    /// Construct a new Chive instance from a vector of bytes.
281    /// No validation of the contents is performed.
282    pub fn from_vec(data: Vec<u8>) -> Chive {
283        Chive { data }
284    }
285}
286
287/// ChiveIn is used to serialize user-provided data in to a [Chive] instance.
288pub struct ChiveIn<'a> {
289    /// Mutable reference to a vector of bytes which all serialized data
290    /// will be written to
291    data: &'a mut Vec<u8>,
292}
293
294/// Private methods
295impl<'a> ChiveIn<'a> {
296    /// Create a new ChiveIn instance that will deserialize the given bytes
297    fn new(data: &'a mut Vec<u8>) -> ChiveIn<'a> {
298        ChiveIn { data }
299    }
300
301    /// Helper method to write a primitive
302    fn write_primitive<T: PrimitiveReadWrite>(&mut self, x: T) {
303        self.data.reserve(u8::SIZE + T::SIZE);
304        self.data.push(ValueType::Primitive(T::TYPE).to_byte());
305        x.write_to(self.data);
306    }
307
308    /// Helper method to write a slice of primitives
309    fn write_primitive_array_slice<T: PrimitiveReadWrite>(&mut self, x: &[T]) {
310        self.data
311            .reserve(u8::SIZE + u32::SIZE + (x.len() * T::SIZE));
312        self.data.push(ValueType::Array(T::TYPE).to_byte());
313        let len = x.len() as u32;
314        len.write_to(self.data);
315        for xi in x {
316            xi.write_to(self.data);
317        }
318    }
319
320    /// Helper method to write an iterator of primitives
321    fn write_primitive_array_iter<I: Iterator>(&mut self, mut it: I)
322    where
323        I::Item: PrimitiveReadWrite,
324    {
325        self.data.push(ValueType::Array(I::Item::TYPE).to_byte());
326        let array_start_index = self.data.len();
327        let mut n_items: u32 = 0;
328        n_items.write_to(self.data);
329        while let Some(x) = it.next() {
330            x.write_to(self.data);
331            n_items += 1;
332        }
333        for (i, b) in n_items.to_be_bytes().iter().enumerate() {
334            self.data[array_start_index + i] = *b;
335        }
336    }
337}
338
339/// Public methods
340impl<'a> ChiveIn<'a> {
341    /// Write a single u8 value
342    pub fn u8(&mut self, x: u8) {
343        self.write_primitive::<u8>(x);
344    }
345
346    /// Write a single i8 value
347    pub fn i8(&mut self, x: i8) {
348        self.write_primitive::<i8>(x);
349    }
350
351    /// Write a single u16 value
352    pub fn u16(&mut self, x: u16) {
353        self.write_primitive::<u16>(x);
354    }
355
356    /// Write a single i16 value
357    pub fn i16(&mut self, x: i16) {
358        self.write_primitive::<i16>(x);
359    }
360
361    /// Write a single u32 value
362    pub fn u32(&mut self, x: u32) {
363        self.write_primitive::<u32>(x);
364    }
365
366    /// Write a single i32 value
367    pub fn i32(&mut self, x: i32) {
368        self.write_primitive::<i32>(x);
369    }
370
371    /// Write a single u64 value
372    pub fn u64(&mut self, x: u64) {
373        self.write_primitive::<u64>(x);
374    }
375
376    /// Write a single i64 value
377    pub fn i64(&mut self, x: i64) {
378        self.write_primitive::<i64>(x);
379    }
380
381    /// Write a single f32 value
382    pub fn f32(&mut self, x: f32) {
383        self.write_primitive::<f32>(x);
384    }
385
386    /// Write a single f64 value
387    pub fn f64(&mut self, x: f64) {
388        self.write_primitive::<f64>(x);
389    }
390
391    /// Write an array of u8 values from a slice
392    pub fn array_slice_u8(&mut self, x: &[u8]) {
393        self.write_primitive_array_slice::<u8>(x);
394    }
395
396    /// Write an array of i8 values from a slice
397    pub fn array_slice_i8(&mut self, x: &[i8]) {
398        self.write_primitive_array_slice::<i8>(x);
399    }
400
401    /// Write an array of u16 values from a slice
402    pub fn array_slice_u16(&mut self, x: &[u16]) {
403        self.write_primitive_array_slice::<u16>(x);
404    }
405
406    /// Write an array of i16 values from a slice
407    pub fn array_slice_i16(&mut self, x: &[i16]) {
408        self.write_primitive_array_slice::<i16>(x);
409    }
410
411    /// Write an array of u32 values from a slice
412    pub fn array_slice_u32(&mut self, x: &[u32]) {
413        self.write_primitive_array_slice::<u32>(x);
414    }
415
416    /// Write an array of i32 values from a slice
417    pub fn array_slice_i32(&mut self, x: &[i32]) {
418        self.write_primitive_array_slice::<i32>(x);
419    }
420
421    /// Write an array of u64 values from a slice
422    pub fn array_slice_u64(&mut self, x: &[u64]) {
423        self.write_primitive_array_slice::<u64>(x);
424    }
425
426    /// Write an array of i64 values from a slice
427    pub fn array_slice_i64(&mut self, x: &[i64]) {
428        self.write_primitive_array_slice::<i64>(x);
429    }
430
431    /// Write an array of f32 values from a slice
432    pub fn array_slice_f32(&mut self, x: &[f32]) {
433        self.write_primitive_array_slice::<f32>(x);
434    }
435
436    /// Write an array of f64 values from a slice
437    pub fn array_slice_f64(&mut self, x: &[f64]) {
438        self.write_primitive_array_slice::<f64>(x);
439    }
440
441    /// Write an array of u8 values from an iterator
442    pub fn array_iter_u8<I: Iterator<Item = u8>>(&mut self, it: I) {
443        self.write_primitive_array_iter(it);
444    }
445
446    /// Write an array of i8 values from an iterator
447    pub fn array_iter_i8<I: Iterator<Item = i8>>(&mut self, it: I) {
448        self.write_primitive_array_iter(it);
449    }
450
451    /// Write an array of u16 values from an iterator
452    pub fn array_iter_u16<I: Iterator<Item = u16>>(&mut self, it: I) {
453        self.write_primitive_array_iter(it);
454    }
455
456    /// Write an array of i16 values from an iterator
457    pub fn array_iter_i16<I: Iterator<Item = i16>>(&mut self, it: I) {
458        self.write_primitive_array_iter(it);
459    }
460
461    /// Write an array of u32 values from an iterator
462    pub fn array_iter_u32<I: Iterator<Item = u32>>(&mut self, it: I) {
463        self.write_primitive_array_iter(it);
464    }
465
466    /// Write an array of i32 values from an iterator
467    pub fn array_iter_i32<I: Iterator<Item = i32>>(&mut self, it: I) {
468        self.write_primitive_array_iter(it);
469    }
470
471    /// Write an array of u64 values from an iterator
472    pub fn array_iter_u64<I: Iterator<Item = u64>>(&mut self, it: I) {
473        self.write_primitive_array_iter(it);
474    }
475
476    /// Write an array of i64 values from an iterator
477    pub fn array_iter_i64<I: Iterator<Item = i64>>(&mut self, it: I) {
478        self.write_primitive_array_iter(it);
479    }
480
481    /// Write an array of f32 values from an iterator
482    pub fn array_iter_f32<I: Iterator<Item = f32>>(&mut self, it: I) {
483        self.write_primitive_array_iter(it);
484    }
485
486    /// Write an array of f64 values from an iterator
487    pub fn array_iter_f64<I: Iterator<Item = f64>>(&mut self, it: I) {
488        self.write_primitive_array_iter(it);
489    }
490
491    /// Write a string
492    pub fn string(&mut self, x: &str) {
493        let bytes = x.as_bytes();
494        self.data.reserve(u8::SIZE + u32::SIZE + bytes.len());
495        self.data.push(ValueType::String.to_byte());
496        let len = bytes.len() as u32;
497        len.write_to(self.data);
498        for b in bytes {
499            self.data.push(*b);
500        }
501    }
502
503    /// Write a nested sub-chive. This creates a contiguous section of bytes
504    /// which is cleanly separated from all data before and after the nested
505    /// sub-chive. This is useful for separating concerns and (de)serializing
506    /// separate complex data structures without fear that deserializing one
507    ///  may read off the end and into the start of the next.
508    pub fn nest<F: FnOnce(ChiveIn)>(&mut self, f: F) {
509        self.data.push(ValueType::Nest.to_byte());
510
511        let prefix_index = self.data.len();
512
513        self.data.push(0);
514        self.data.push(0);
515        self.data.push(0);
516        self.data.push(0);
517
518        let len_before = self.data.len();
519
520        f(ChiveIn::new(self.data));
521
522        let len_after = self.data.len();
523        debug_assert!(len_after >= len_before);
524        let len = (len_after - len_before) as u32;
525        let [b0, b1, b2, b3] = len.to_be_bytes();
526
527        self.data[prefix_index + 0] = b0;
528        self.data[prefix_index + 1] = b1;
529        self.data[prefix_index + 2] = b2;
530        self.data[prefix_index + 3] = b3;
531    }
532
533    /// Write a user-provided object which implements Chivable
534    pub fn chivable<T: Chivable>(&mut self, chivable: &T) {
535        chivable.chive_in(self);
536    }
537}
538
539/// Iterator for reading values out of a serialized array in a [Chive] instance
540/// one value at a time.
541pub struct ChiveOutIterator<'a, T> {
542    /// A ChiveOut instance pointing to a slice of serialized data containing an array
543    chive_out: ChiveOut<'a>,
544
545    /// PhantomData used to bake the type parameter T into the iterator
546    _phantom_data: PhantomData<T>,
547}
548
549impl<'a, T> ChiveOutIterator<'a, T> {
550    /// Construct a new ChiveOutIterator. The chive_out instance is expected
551    /// to point to an homogenous array of serialized primitive values.
552    fn new(chive_out: ChiveOut<'a>) -> ChiveOutIterator<'a, T>
553    where
554        T: PrimitiveReadWrite,
555    {
556        debug_assert_eq!(chive_out.remaining_len() % T::SIZE, 0);
557        ChiveOutIterator {
558            chive_out,
559            _phantom_data: PhantomData,
560        }
561    }
562}
563
564/// Iterator implementation for ChiveOutIterator
565impl<'a, T: PrimitiveReadWrite> Iterator for ChiveOutIterator<'a, T> {
566    type Item = T;
567
568    fn next(&mut self) -> Option<T> {
569        if self.chive_out.is_empty() {
570            return None;
571        }
572        debug_assert!(self.chive_out.remaining_len() >= T::SIZE);
573        Some(T::read_from(&mut self.chive_out))
574    }
575}
576
577/// ExactSizeIterator implementation for ChiveOutIterator
578impl<'a, T: PrimitiveReadWrite> ExactSizeIterator for ChiveOutIterator<'a, T> {
579    fn len(&self) -> usize {
580        debug_assert_eq!(self.chive_out.remaining_len() % T::SIZE, 0);
581        self.chive_out.remaining_len() / T::SIZE
582    }
583}
584
585/// ChiveOut is used to deserialize data out of an existing [Chive] instance.
586pub struct ChiveOut<'a> {
587    data: &'a [u8],
588    position: usize,
589}
590
591/// Private methods
592impl<'a> ChiveOut<'a> {
593    /// Create a new ChiveOut instance for deserializing the given slice of bytes
594    fn new(data: &'a [u8]) -> ChiveOut<'a> {
595        ChiveOut { data, position: 0 }
596    }
597
598    /// Get the number of bytes that have yet to be read
599    fn remaining_len(&self) -> usize {
600        let l = self.data.len();
601        debug_assert!(self.position <= l);
602        return l - self.position;
603    }
604
605    /// Read the next byte and advance past it
606    fn read_byte(&mut self) -> Result<u8, ()> {
607        if self.position >= self.data.len() {
608            Err(())
609        } else {
610            let b = self.data[self.position];
611            self.position += 1;
612            Ok(b)
613        }
614    }
615
616    /// Read the next byte without advancing past it
617    fn peek_byte(&self, offset: usize) -> Result<u8, ()> {
618        if (self.position + offset) >= self.data.len() {
619            Err(())
620        } else {
621            Ok(self.data[self.position + offset])
622        }
623    }
624
625    /// Try to perform an operation, get its result, and
626    /// rollback the position in the underlying byte vector
627    /// if it failed.
628    fn reset_on_error<T: 'a, F: FnOnce(&mut ChiveOut<'a>) -> Result<T, ()>>(
629        &mut self,
630        f: F,
631    ) -> Result<T, ()> {
632        let original_position = self.position;
633        let result = f(self);
634        if result.is_err() {
635            self.position = original_position;
636        }
637        result
638    }
639
640    /// Read a single primitive, checking for its type tag first and then
641    /// reading its value
642    fn read_primitive<T: PrimitiveReadWrite + 'static>(&mut self) -> Result<T, ()> {
643        self.reset_on_error(|d| {
644            if d.remaining_len() < (u8::SIZE + T::SIZE) {
645                return Err(());
646            }
647            let the_type = ValueType::from_byte(d.read_byte()?)?;
648            if the_type != ValueType::Primitive(T::TYPE) {
649                return Err(());
650            }
651            Ok(T::read_from(d))
652        })
653    }
654
655    /// Read an array of primitives to a vector, checking for its tag type and length
656    /// first and then reading its values
657    fn read_primitive_array_slice<T: PrimitiveReadWrite + 'static>(
658        &mut self,
659    ) -> Result<Vec<T>, ()> {
660        self.reset_on_error(|d| {
661            if d.remaining_len() < (u8::SIZE + u32::SIZE) {
662                return Err(());
663            }
664            let the_type = ValueType::from_byte(d.read_byte()?)?;
665            if the_type != ValueType::Array(T::TYPE) {
666                return Err(());
667            }
668            let len = u32::read_from(d) as usize;
669            if d.remaining_len() < (len * T::SIZE) {
670                return Err(());
671            }
672            Ok((0..len).map(|_| T::read_from(d)).collect())
673        })
674    }
675
676    /// Create an iterator that visits all primitives in an array, first checking
677    /// the tag type and length.
678    fn read_primitive_array_iter<'b, T: PrimitiveReadWrite + 'static>(
679        &'b mut self,
680    ) -> Result<ChiveOutIterator<'b, T>, ()> {
681        self.reset_on_error(|d| {
682            if d.remaining_len() < (u8::SIZE + u32::SIZE) {
683                return Err(());
684            }
685            let the_type = ValueType::from_byte(d.read_byte()?)?;
686            if the_type != ValueType::Array(T::TYPE) {
687                return Err(());
688            }
689            let len = u32::read_from(d) as usize;
690            let byte_len = len * T::SIZE;
691            if d.remaining_len() < byte_len {
692                return Err(());
693            }
694            let d2 = ChiveOut::new(&d.data[d.position..d.position + byte_len]);
695            d.position += byte_len;
696            Ok(ChiveOutIterator::new(d2))
697        })
698    }
699}
700
701/// Public methods
702impl<'a> ChiveOut<'a> {
703    /// Read a single u8 value
704    pub fn u8(&mut self) -> Result<u8, ()> {
705        self.read_primitive::<u8>()
706    }
707
708    /// Read a single i8 value
709    pub fn i8(&mut self) -> Result<i8, ()> {
710        self.read_primitive::<i8>()
711    }
712
713    /// Read a single u16 value
714    pub fn u16(&mut self) -> Result<u16, ()> {
715        self.read_primitive::<u16>()
716    }
717
718    /// Read a single i16 value
719    pub fn i16(&mut self) -> Result<i16, ()> {
720        self.read_primitive::<i16>()
721    }
722
723    /// Read a single u32 value
724    pub fn u32(&mut self) -> Result<u32, ()> {
725        self.read_primitive::<u32>()
726    }
727
728    /// Read a single i32 value
729    pub fn i32(&mut self) -> Result<i32, ()> {
730        self.read_primitive::<i32>()
731    }
732
733    /// Read a single u64 value
734    pub fn u64(&mut self) -> Result<u64, ()> {
735        self.read_primitive::<u64>()
736    }
737
738    /// Read a single i64 value
739    pub fn i64(&mut self) -> Result<i64, ()> {
740        self.read_primitive::<i64>()
741    }
742
743    /// Read a single f32 value
744    pub fn f32(&mut self) -> Result<f32, ()> {
745        self.read_primitive::<f32>()
746    }
747
748    /// Read a single f64 value
749    pub fn f64(&mut self) -> Result<f64, ()> {
750        self.read_primitive::<f64>()
751    }
752
753    /// Read an array of u8 values into a Vec
754    pub fn array_slice_u8(&mut self) -> Result<Vec<u8>, ()> {
755        self.read_primitive_array_slice::<u8>()
756    }
757
758    /// Read an array of i8 values into a Vec
759    pub fn array_slice_i8(&mut self) -> Result<Vec<i8>, ()> {
760        self.read_primitive_array_slice::<i8>()
761    }
762
763    /// Read an array of u16 values into a Vec
764    pub fn array_slice_u16(&mut self) -> Result<Vec<u16>, ()> {
765        self.read_primitive_array_slice::<u16>()
766    }
767
768    /// Read an array of i16 values into a Vec
769    pub fn array_slice_i16(&mut self) -> Result<Vec<i16>, ()> {
770        self.read_primitive_array_slice::<i16>()
771    }
772
773    /// Read an array of u32 values into a Vec
774    pub fn array_slice_u32(&mut self) -> Result<Vec<u32>, ()> {
775        self.read_primitive_array_slice::<u32>()
776    }
777
778    /// Read an array of i32 values into a Vec
779    pub fn array_slice_i32(&mut self) -> Result<Vec<i32>, ()> {
780        self.read_primitive_array_slice::<i32>()
781    }
782
783    /// Read an array of u64 values into a Vec
784    pub fn array_slice_u64(&mut self) -> Result<Vec<u64>, ()> {
785        self.read_primitive_array_slice::<u64>()
786    }
787
788    /// Read an array of i64 values into a Vec
789    pub fn array_slice_i64(&mut self) -> Result<Vec<i64>, ()> {
790        self.read_primitive_array_slice::<i64>()
791    }
792
793    /// Read an array of f32 values into a Vec
794    pub fn array_slice_f32(&mut self) -> Result<Vec<f32>, ()> {
795        self.read_primitive_array_slice::<f32>()
796    }
797
798    /// Read an array of f64 values into a Vec
799    pub fn array_slice_f64(&mut self) -> Result<Vec<f64>, ()> {
800        self.read_primitive_array_slice::<f64>()
801    }
802
803    /// Read an array of u8 values into an iterator
804    pub fn array_iter_u8<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, u8>, ()> {
805        self.read_primitive_array_iter::<u8>()
806    }
807
808    /// Read an array of i8 values into an iterator
809    pub fn array_iter_i8<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, i8>, ()> {
810        self.read_primitive_array_iter::<i8>()
811    }
812
813    /// Read an array of u16 values into an iterator
814    pub fn array_iter_u16<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, u16>, ()> {
815        self.read_primitive_array_iter::<u16>()
816    }
817
818    /// Read an array of i16 values into an iterator
819    pub fn array_iter_i16<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, i16>, ()> {
820        self.read_primitive_array_iter::<i16>()
821    }
822
823    /// Read an array of u32 values into an iterator
824    pub fn array_iter_u32<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, u32>, ()> {
825        self.read_primitive_array_iter::<u32>()
826    }
827
828    /// Read an array of i32 values into an iterator
829    pub fn array_iter_i32<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, i32>, ()> {
830        self.read_primitive_array_iter::<i32>()
831    }
832
833    /// Read an array of u64 values into an iterator
834    pub fn array_iter_u64<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, u64>, ()> {
835        self.read_primitive_array_iter::<u64>()
836    }
837
838    /// Read an array of i64 values into an iterator
839    pub fn array_iter_i64<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, i64>, ()> {
840        self.read_primitive_array_iter::<i64>()
841    }
842
843    /// Read an array of f32 values into an iterator
844    pub fn array_iter_f32<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, f32>, ()> {
845        self.read_primitive_array_iter::<f32>()
846    }
847
848    /// Read an array of f64 values into an iterator
849    pub fn array_iter_f64<'b>(&'b mut self) -> Result<ChiveOutIterator<'b, f64>, ()> {
850        self.read_primitive_array_iter::<f64>()
851    }
852
853    /// Read a string
854    pub fn string(&mut self) -> Result<String, ()> {
855        if self.remaining_len() < (u8::SIZE + u32::SIZE) {
856            return Err(());
857        }
858        let the_type = ValueType::from_byte(self.read_byte()?)?;
859        if the_type != ValueType::String {
860            return Err(());
861        }
862        let len = u32::read_from(self) as usize;
863        if self.remaining_len() < len {
864            return Err(());
865        }
866        let slice = &self.data[self.position..(self.position + len)];
867        self.position += len;
868        let str_slice = std::str::from_utf8(slice).map_err(|_| ())?;
869        Ok(str_slice.to_string())
870    }
871
872    /// Read a nested sub-chive
873    pub fn nest<'b>(&'b mut self) -> Result<ChiveOut<'b>, ()> {
874        if self.remaining_len() < (u8::SIZE + u32::SIZE) {
875            return Err(());
876        }
877        let the_type = ValueType::from_byte(self.read_byte()?)?;
878        if the_type != ValueType::Nest {
879            return Err(());
880        }
881        let len = u32::read_from(self) as usize;
882        if self.remaining_len() < len {
883            return Err(());
884        }
885        let nest_slice: &[u8] = &self.data[self.position..(self.position + len)];
886        self.position += len;
887        Ok(ChiveOut::new(nest_slice))
888    }
889
890    /// Read a user-provided object which implements Chivable.
891    /// The type of the object is not checked, only the types
892    /// of individual values.
893    pub fn chivable<T: Chivable>(&mut self) -> Result<T, ()> {
894        T::chive_out(self)
895    }
896
897    /// Read the type of the next value
898    pub fn peek_type(&self) -> Result<ValueType, ()> {
899        ValueType::from_byte(self.peek_byte(0)?)
900    }
901
902    /// If the next type is an array, string, or nested chive,
903    /// get its length, in bytes
904    pub fn peek_length_bytes(&self) -> Result<usize, ()> {
905        let the_type = ValueType::from_byte(self.peek_byte(0)?)?;
906        if let ValueType::Primitive(_) = the_type {
907            return Err(());
908        }
909        Ok(u32::from_be_bytes([
910            self.peek_byte(1)?,
911            self.peek_byte(2)?,
912            self.peek_byte(3)?,
913            self.peek_byte(4)?,
914        ]) as usize)
915    }
916
917    /// Returns true iff the chive contains no more data to read
918    pub fn is_empty(&self) -> bool {
919        return self.position == self.data.len();
920    }
921}