protocol/
parcel.rs

1use crate::{hint, Error, Settings};
2use std::io::prelude::*;
3use std::io;
4
5/// A value which can be read and written.
6///
7/// All of the expected standard Rust types implement this.
8///
9/// Types that implement `Parcel` include (not exhaustive):
10///
11///   * The Rust primitive types
12///     * `u8`, `i8`, `u16`, `i16` ... `u64`
13///     * `bool`, `char`
14///     * `f32`, `f64`
15///     * Tuples
16///       * `(T1) where T1: Parcel`
17///       * `(T1, T2) where T1: Parcel, T2: Parcel`
18///       * `(T1, T2, ... Tn) where T1: Parcel, T2: Parcel, ... Tn: Parcel`
19///     * Arrays
20///       * `[T; 0] where T: Parcel`
21///       * `[T; 1] where T: Parcel`
22///       * `[T; 2] where T: Parcel`
23///       * `[T; 32] where T: Parcel`
24///       * `[T; 40] where T: Parcel`
25///       * `[T; 42] where T: Parcel`
26///       * ...
27///       * `[T; 64] where T: Parcel`
28///       * ...
29///       * `[T; 1024] where T: Parcel`
30///     * `String`
31///     * `Option<T: Parcel>`
32///     * `Box<T: Parcel>`
33///     * `std::ops::Range<T: Parcel>`
34///     * Smart pointers
35///       * `std::rc::Rc`
36///       * `std::sync::Arc`
37///     * `std::collections`
38///       * `Vec<T: Parcel>`
39///       * `VecDeque<T: Parcel>`
40///       * `HashMap<T: Parcel>`
41///       * `BTreeMap<T: Parcel>`
42pub trait Parcel : Sized
43{
44    /// The textual name of the type.
45    const TYPE_NAME: &'static str;
46
47    /// Reads a new item with a fresh set of hints.
48    ///
49    /// Blocks until a value is received.
50    fn read(read: &mut dyn Read,
51            settings: &Settings) -> Result<Self, Error> {
52        Self::read_field(read, settings, &mut hint::Hints::default())
53    }
54
55    /// Reads a value from a stream.
56    ///
57    /// Parameters:
58    ///
59    ///   * `hints` - a list of hints accessible by the current
60    ///   parcel chain only.
61    ///
62    /// Blocks until a value is received.
63    fn read_field(read: &mut dyn Read,
64                  settings: &Settings,
65                  hints: &mut hint::Hints) -> Result<Self, Error>;
66
67    /// Writes a value to a stream.
68    fn write(&self, write: &mut dyn Write,
69             settings: &Settings) -> Result<(), Error> {
70        self.write_field(write, settings, &mut hint::Hints::default())
71    }
72
73    /// Writes a value to a stream.
74    fn write_field(&self, write: &mut dyn Write,
75             settings: &Settings,
76             hints: &mut hint::Hints) -> Result<(), Error>;
77
78    /// Convers the value into a byte stream that implements `std::io::Read`.
79    fn into_stream(self, settings: &Settings)
80        -> Result<io::Cursor<Vec<u8>>, Error> {
81        self.raw_bytes(settings).map(io::Cursor::new)
82    }
83
84    /// Parses a new value from its raw byte representation.
85    ///
86    /// Returns `Err` if the bytes represent an invalid value.
87    fn from_raw_bytes(bytes: &[u8],
88                      settings: &Settings) -> Result<Self, Error> {
89        let mut hints = hint::Hints::default();
90        Self::field_from_raw_bytes(bytes, settings, &mut hints)
91    }
92
93    /// Parses a new value from its raw byte representation.
94    ///
95    /// Returns `Err` if the bytes represent an invalid value.
96    fn field_from_raw_bytes(bytes: &[u8],
97                            settings: &Settings,
98                            hints: &mut hint::Hints) -> Result<Self, Error> {
99        let mut buffer = ::std::io::Cursor::new(bytes);
100        Self::read_field(&mut buffer, settings, hints)
101    }
102
103
104    /// Gets the raw byte representation of the value.
105    fn raw_bytes(&self, settings: &Settings) -> Result<Vec<u8>, Error> {
106        self.raw_bytes_field(settings, &mut hint::Hints::default())
107    }
108
109    /// Gets the raw bytes of this type as a field of a larger type.
110    fn raw_bytes_field(&self,
111                       settings: &Settings,
112                       hints: &mut hint::Hints) -> Result<Vec<u8>, Error> {
113        let mut buffer = io::Cursor::new(Vec::new());
114        self.write_field(&mut buffer, settings, hints)?;
115
116        Ok(buffer.into_inner())
117    }
118
119    /// Gets the name of the type; `Parcel::TYPE_NAME`.
120    fn type_name(&self) -> &'static str { Self::TYPE_NAME }
121}
122