sheave_core/messages/amf/v0/
boolean.rs

1use std::{
2    cmp::Ordering,
3    fmt::{
4        Display,
5        Formatter,
6        Result as FormatResult
7    },
8    io::Result as IOResult
9};
10use super::{
11    Marker,
12    super::ensure_marker
13};
14use crate::{
15    Decoder,
16    Encoder,
17    ByteBuffer
18};
19
20/// The boolean representation of AMF data types.
21/// This uses 1 byte integer as a boolean value.
22/// Usually, `0` is treated as `false`, else is `true`.
23///
24/// # Examples
25///
26/// ```rust
27/// use sheave_core::messages::amf::v0::Boolean;
28///
29/// assert_eq!(false, Boolean::new(0));
30/// assert_eq!(true, Boolean::new(1));
31/// assert_eq!(true, Boolean::new(u8::MAX))
32/// ```
33#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
34pub struct Boolean(u8);
35
36impl Boolean {
37    /// Constructs an AMF's Boolean.
38    pub fn new(boolean: u8) -> Self {
39        Self(boolean)
40    }
41
42    /// Gets an inner value as a boolean value.
43    pub fn as_boolean(&self) -> bool {
44        self.0 > 0
45    }
46}
47
48impl Display for Boolean {
49    fn fmt(&self, f: &mut Formatter<'_>) -> FormatResult {
50        writeln!(f, "{}", self.0 != 0)
51    }
52}
53
54impl PartialEq<bool> for Boolean {
55    fn eq(&self, other: &bool) -> bool {
56        self.as_boolean().eq(other)
57    }
58}
59
60impl PartialEq<Boolean> for bool {
61    fn eq(&self, other: &Boolean) -> bool {
62        self.eq(&other.as_boolean())
63    }
64}
65
66impl PartialOrd<bool> for Boolean {
67    fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
68        self.as_boolean().partial_cmp(other)
69    }
70}
71
72impl PartialOrd<Boolean> for bool {
73    fn partial_cmp(&self, other: &Boolean) -> Option<Ordering> {
74        self.partial_cmp(&other.as_boolean())
75    }
76}
77
78impl Decoder<Boolean> for ByteBuffer {
79    /// Decodes bytes into an AMF's Boolean.
80    ///
81    /// # Errors
82    ///
83    /// * [`InsufficientBufferLength`]
84    ///
85    /// When buffer isn't remained at least 2 bytes.
86    ///
87    /// * [`InconsistentMarker`]
88    ///
89    /// When a marker byte doesn't indicate the AMF Boolean.
90    ///
91    /// # Examples
92    ///
93    /// ```rust
94    /// use sheave_core::{
95    ///     ByteBuffer,
96    ///     Decoder,
97    ///     messages::amf::v0::{
98    ///         Marker,
99    ///         Boolean
100    ///     }
101    /// };
102    ///
103    /// let mut buffer = ByteBuffer::default();
104    /// buffer.put_u8(Marker::Boolean as u8);
105    /// buffer.put_u8(0);
106    /// assert!(Decoder::<Boolean>::decode(&mut buffer).is_ok());
107    ///
108    /// let mut buffer = ByteBuffer::default();
109    /// buffer.put_u8(Marker::Number as u8);
110    /// buffer.put_u8(0);
111    /// assert!(Decoder::<Boolean>::decode(&mut buffer).is_err());
112    ///
113    /// let mut buffer = ByteBuffer::default();
114    /// assert!(Decoder::<Boolean>::decode(&mut buffer).is_err())
115    /// ```
116    ///
117    /// [`InsufficientBufferLength`]: crate::byte_buffer::InsufficientBufferLength
118    /// [`InconsistentMarker`]: crate::messages::amf::InconsistentMarker
119    fn decode(&mut self) -> IOResult<Boolean> {
120        self.get_u8().and_then(
121            |marker| ensure_marker(Marker::Boolean as u8, marker)
122        )?;
123
124        self.get_u8().map(Boolean::new)
125    }
126}
127
128impl Encoder<Boolean> for ByteBuffer {
129    /// Encodes an AMF's Boolean into bytes.
130    fn encode(&mut self, boolean: &Boolean) {
131        self.put_u8(Marker::Boolean as u8);
132        self.put_u8(boolean.0);
133    }
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139
140    #[test]
141    fn decode_boolean() {
142        let mut buffer = ByteBuffer::default();
143        buffer.put_u8(Marker::Boolean as u8);
144        buffer.put_u8(0);
145        let result: IOResult<Boolean> = buffer.decode();
146        assert!(result.is_ok());
147        let boolean = result.unwrap();
148        assert!(!boolean.as_boolean())
149    }
150
151    #[test]
152    fn encode_boolean() {
153        let mut buffer = ByteBuffer::default();
154        buffer.encode(&Boolean::new(0));
155        let result: Vec<u8> = buffer.into();
156        assert_eq!(Marker::Boolean as u8, result[0]);
157        assert_eq!(0, result[1])
158    }
159}