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