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}