network_audio_protocol/lib.rs
1#[cfg(test)]
2mod tests
3{
4 mod message_type
5 {
6 use super::super::*;
7
8 #[test]
9 fn from_u8_test()
10 {
11 assert_eq!(MessageType::Null, MessageType::from(0));
12 assert_eq!(MessageType::Get, MessageType::from(1));
13 assert_eq!(MessageType::Reply, MessageType::from(2));
14 assert_eq!(MessageType::Error, MessageType::from(3));
15 assert_eq!(MessageType::Shutdown, MessageType::from(4));
16 assert_eq!(MessageType::Unknown, MessageType::from(5));
17 }
18
19 #[test]
20 fn as_u8_test()
21 {
22 assert_eq!(MessageType::Null.as_u8(), 0);
23 assert_eq!(MessageType::Get.as_u8(), 1);
24 assert_eq!(MessageType::Reply.as_u8(), 2);
25 assert_eq!(MessageType::Error.as_u8(), 3);
26 assert_eq!(MessageType::Shutdown.as_u8(), 4);
27 assert_eq!(MessageType::Unknown.as_u8(), 255);
28 }
29
30 #[test]
31 fn to_string_test()
32 {
33 assert_eq!(String::from("Null"), MessageType::Null.to_string());
34 assert_eq!(String::from("Get"), MessageType::Get.to_string());
35 assert_eq!(String::from("Reply"), MessageType::Reply.to_string());
36 assert_eq!(String::from("Error"), MessageType::Error.to_string());
37 assert_eq!(String::from("Shutdown"), MessageType::Shutdown.to_string());
38 assert_eq!(String::from("Unknown"), MessageType::Unknown.to_string());
39 }
40
41 }
42
43 mod data_type
44 {
45 use super::super::*;
46
47 #[test]
48 fn from_u8_test()
49 {
50 assert_eq!(DataType::Null, DataType::from(0));
51 assert_eq!(DataType::SampleRate, DataType::from(1));
52 assert_eq!(DataType::SampleFormat, DataType::from(2));
53 assert_eq!(DataType::ChannelCount, DataType::from(3));
54 assert_eq!(DataType::AudioSamples, DataType::from(4));
55 assert_eq!(DataType::Unknown, DataType::from(255));
56 }
57
58 #[test]
59 fn as_u8_test()
60 {
61 assert_eq!(DataType::Null.as_u8(), 0);
62 assert_eq!(DataType::SampleRate.as_u8(), 1);
63 assert_eq!(DataType::SampleFormat.as_u8(), 2);
64 assert_eq!(DataType::ChannelCount.as_u8(), 3);
65 assert_eq!(DataType::AudioSamples.as_u8(), 4);
66 assert_eq!(DataType::Unknown.as_u8(), 255);
67 }
68
69 #[test]
70 fn to_string_test()
71 {
72 assert_eq!(DataType::Null.to_string(), String::from("Null"));
73 assert_eq!(DataType::SampleRate.to_string(), String::from("SampleRate"));
74 assert_eq!(DataType::SampleFormat.to_string(), String::from("SampleFormat"));
75 assert_eq!(DataType::ChannelCount.to_string(), String::from("ChannelCount"));
76 assert_eq!(DataType::AudioSamples.to_string(), String::from("AudioSamples"));
77 assert_eq!(DataType::Unknown.to_string(), String::from("Unknown"));
78 }
79 }
80}
81
82/// A listing of all the different kinds of message types that a Message
83/// can be composed of.
84///
85/// # Description #
86/// The Message Type variants are put at the beginning of a network message, and
87/// determine what kind of message the network message will be. Each variant of
88/// the MessageType enum maps to a u8 integer, a MessageType
89/// variant can also be created from a u8 integer.
90///
91/// # u8 Variant Mappings #
92/// * `Null == 0`
93/// * `Get == 1`
94/// * `Reply == 2`
95/// * `Error == 3`
96/// * `Shutdown == 4`
97/// * `Unknown >= 5`
98/// # Examples #
99/// ```
100/// use network_audio_protocol::MessageType;
101///
102/// let message_type: MessageType = MessageType::from(1);
103/// assert_eq!(message_type, MessageType::Get);
104/// assert_eq!(message_type.to_string(), String::from("Get"));
105///
106/// println!("Message Type: {}, maps to: {}", message_type, message_type.as_u8());
107/// ```
108/// The above code creates a `MessageType` variant from the u8 integer `1`, confirms that it is
109/// equal to `MessageType::Get`, turns the `MessageType` into a `String`, and compares it to
110/// another string value, and finally prints the `MessageType` and its corresponding u8 value
111#[derive(Debug)]
112#[derive(PartialEq)]
113pub enum MessageType
114{
115 /// The `Null` variant is used to create a null, or empty message.
116 Null,
117 /// The `Get` variant is used to create a message that contains a request within it.
118 Get,
119 /// The `Reply` variant is used to create a message that contains data to fufill a `Get`
120 /// request.
121 Reply,
122 /// The `Error` variant is used to create a message indicating an error occurred.
123 Error,
124 /// The `Shutdown` variant is used to create a shutdown / termination message.
125 Shutdown,
126 /// The `Unkown` variant is not used to make any messages, but rather to represent a message of
127 /// an unknown type.
128 Unknown,
129}
130
131impl MessageType
132{
133 /// Returns the corresponding u8 integer value for the used `MessageType` variant. Unlike
134 /// `Into` it does not consume self.
135 pub fn as_u8(&self) -> u8
136 {
137 return match self
138 {
139 MessageType::Null => 0,
140 MessageType::Get => 1,
141 MessageType::Reply => 2,
142 MessageType::Error => 3,
143 MessageType::Shutdown => 4,
144 MessageType::Unknown => 255,
145 };
146 }
147}
148
149impl From<u8> for MessageType
150{
151 fn from(byte: u8) -> Self
152 {
153 return match byte
154 {
155 0 => MessageType::Null,
156 1 => MessageType::Get,
157 2 => MessageType::Reply,
158 3 => MessageType::Error,
159 4 => MessageType::Shutdown,
160 _ => MessageType::Unknown,
161 };
162 }
163}
164
165impl std::fmt::Display for MessageType
166{
167 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error>
168 {
169 let string: String = match self
170 {
171 MessageType::Null => String::from("Null"),
172 MessageType::Get => String::from("Get"),
173 MessageType::Reply => String::from("Reply"),
174 MessageType::Error => String::from("Error"),
175 MessageType::Shutdown => String::from("Shutdown"),
176 MessageType::Unknown => String::from("Unknown"),
177 };
178
179 formatter.write_str(string.as_str())?;
180
181 return Ok(());
182 }
183}
184
185/// A listing of data types used to compose Get and Reply Messages
186///
187/// # Description #
188/// The Data Type enum variants are used to specify what data is contained in a Message, it comes
189/// directly after the Message Type, and is only relevant for `MessageType::Get` and
190/// `MessageType::Reply` Messages. Each variant as a mapping to a u8 integer.
191///
192/// # u8 Variant Mappings #
193/// * `Null == 0`
194/// * `SampleRate == 1`
195/// * `SampleFormat == 2`
196/// * `ChannelCount == 3`
197/// * `AudioSamples == 4`
198/// * `Unknown >= 5`
199///
200/// # Examples #
201///
202/// ```
203/// use network_audio_protocol::DataType;
204///
205/// // create a DataType variant from the integer 1
206/// let data_type: DataType = DataType::from(1);
207///
208/// // turn the DataType variant into a string
209/// let as_string: String = data_type.to_string();
210///
211/// // check for valid results
212/// assert_eq!(DataType::SampleRate, data_type);
213/// assert_eq!(String::from("SampleRate"), as_string);
214///
215/// // print out the DataType variant, and its u8 integer mapping
216/// println!("Data Type: {}, maps to: {}", data_type, data_type.as_u8());
217/// ```
218#[derive(Debug)]
219#[derive(PartialEq)]
220pub enum DataType
221{
222 /// Used to send a Message whithout a data type.
223 Null,
224 /// Used to send a message requesting / containing the audio sample rate or frequency.
225 /// `SampleRate` is represented as a `u32` integer.
226 SampleRate,
227 /// Used to send a message requesting / containing the audio data sample format. `SampleFormat`
228 /// is represented as `(bool, bool, u32)` tuple, where the first boolean is the Endianness of the
229 /// samples `(true == Little Endian)`, the second boolean is the Signedness of the samples `(true
230 /// == Signed)`, and the `u32` is the bit depth of the samples.
231 SampleFormat,
232 /// Used to send a message requesting / containing the number of audio channels. `ChannelCount`
233 /// is represented as a `u32` integer.
234 ChannelCount,
235 /// Used to send a message requesting / containing audio samples / audio data. `AudioSamples`
236 /// are represented as a `u8` slice, or `&[u8]`. The Endianness and Signedness
237 /// of the bytes is not altered when the message is serialized / deserialized.
238 AudioSamples,
239 /// Not formally used in composing messages, but rather for specifying that a message is made up of an
240 /// unknown, or undefined data type.
241 Unknown,
242}
243
244impl DataType
245{
246 pub fn as_u8(&self) -> u8
247 {
248 return match self
249 {
250 DataType::Null => 0,
251 DataType::SampleRate => 1,
252 DataType::SampleFormat => 2,
253 DataType::ChannelCount => 3,
254 DataType::AudioSamples => 4,
255 DataType::Unknown => 255,
256 };
257 }
258}
259
260impl From<u8> for DataType
261{
262 fn from(byte: u8) -> Self
263 {
264 return match byte
265 {
266 0 => DataType::Null,
267 1 => DataType::SampleRate,
268 2 => DataType::SampleFormat,
269 3 => DataType::ChannelCount,
270 4 => DataType::AudioSamples,
271 _ => DataType::Unknown,
272 };
273 }
274}
275
276impl std::fmt::Display for DataType
277{
278 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error>
279 {
280 let string: String = match self
281 {
282 DataType::Null => String::from("Null"),
283 DataType::SampleRate => String::from("SampleRate"),
284 DataType::SampleFormat => String::from("SampleFormat"),
285 DataType::ChannelCount => String::from("ChannelCount"),
286 DataType::AudioSamples => String::from("AudioSamples"),
287 DataType::Unknown => String::from("Unknown"),
288 };
289
290 formatter.write_str(string.as_str())?;
291
292 return Ok(());
293 }
294}