djin_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///     * Smart pointers
34///       * `std::rc::Rc`
35///       * `std::sync::Arc`
36///     * `std::collections`
37///       * `Vec<T: Parcel>`
38///       * `VecDeque<T: Parcel>`
39///       * `HashMap<T: Parcel>`
40///       * `BTreeMap<T: Parcel>`
41pub trait Parcel : Sized
42{
43    /// The textual name of the type.
44    const TYPE_NAME: &'static str;
45
46    /// Reads a new item with a fresh set of hints.
47    ///
48    /// Blocks until a value is received.
49    fn read(read: &mut dyn Read,
50            settings: &Settings) -> Result<Self, Error> {
51        Self::read_field(read, settings, &mut hint::Hints::default())
52    }
53
54    /// Reads a value from a stream.
55    ///
56    /// Parameters:
57    ///
58    ///   * `hints` - a list of hints accessible by the current
59    ///   parcel chain only.
60    ///
61    /// Blocks until a value is received.
62    fn read_field(read: &mut dyn Read,
63                  settings: &Settings,
64                  hints: &mut hint::Hints) -> Result<Self, Error>;
65
66    /// Writes a value to a stream.
67    fn write(&self, write: &mut dyn Write,
68             settings: &Settings) -> Result<(), Error> {
69        self.write_field(write, settings, &mut hint::Hints::default())
70    }
71
72    /// Writes a value to a stream.
73    fn write_field(&self, write: &mut dyn Write,
74             settings: &Settings,
75             hints: &mut hint::Hints) -> Result<(), Error>;
76
77    /// Convers the value into a byte stream that implements `std::io::Read`.
78    fn into_stream(self, settings: &Settings)
79        -> Result<io::Cursor<Vec<u8>>, Error> {
80        self.raw_bytes(settings).map(io::Cursor::new)
81    }
82
83    /// Parses a new value from its raw byte representation.
84    ///
85    /// Returns `Err` if the bytes represent an invalid value.
86    fn from_raw_bytes(bytes: &[u8],
87                      settings: &Settings) -> Result<Self, Error> {
88        let mut hints = hint::Hints::default();
89        Self::field_from_raw_bytes(bytes, settings, &mut hints)
90    }
91
92    /// Parses a new value from its raw byte representation.
93    ///
94    /// Returns `Err` if the bytes represent an invalid value.
95    fn field_from_raw_bytes(bytes: &[u8],
96                            settings: &Settings,
97                            hints: &mut hint::Hints) -> Result<Self, Error> {
98        let mut buffer = ::std::io::Cursor::new(bytes);
99        Self::read_field(&mut buffer, settings, hints)
100    }
101
102
103    /// Gets the raw byte representation of the value.
104    fn raw_bytes(&self, settings: &Settings) -> Result<Vec<u8>, Error> {
105        self.raw_bytes_field(settings, &mut hint::Hints::default())
106    }
107
108    /// Gets the raw bytes of this type as a field of a larger type.
109    fn raw_bytes_field(&self,
110                       settings: &Settings,
111                       hints: &mut hint::Hints) -> Result<Vec<u8>, Error> {
112        let mut buffer = io::Cursor::new(Vec::new());
113        self.write_field(&mut buffer, settings, hints)?;
114
115        Ok(buffer.into_inner())
116    }
117
118    /// Gets the name of the type; `Parcel::TYPE_NAME`.
119    fn type_name(&self) -> &'static str { Self::TYPE_NAME }
120}
121