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