Skip to main content

rsfn_file/header/fields/
nullable_buffer.rs

1use std::fmt;
2
3use super::Buffer;
4
5/// Buffer que pode ser vazio.
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum NullableBuffer {
8    None,
9    Some(Box<Buffer>),
10}
11
12impl TryFrom<Vec<u8>> for NullableBuffer {
13    type Error = Vec<u8>;
14
15    fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
16        let value: [u8; 256] = value.try_into()?;
17        Ok(value.into())
18    }
19}
20
21impl From<[u8; 256]> for NullableBuffer {
22    fn from(value: [u8; 256]) -> Self {
23        if value.iter().all(|&byte| byte == 0) {
24            Self::None
25        } else {
26            Self::Some(Box::new(value.into()))
27        }
28    }
29}
30
31impl NullableBuffer {
32    pub fn value(&self) -> [u8; 256] {
33        match self {
34            Self::None => [0; 256],
35            Self::Some(buffer) => buffer.value(),
36        }
37    }
38
39    pub fn describe_value(&self) -> String {
40        match self {
41            Self::None => "VAZIO".to_string(),
42            Self::Some(buffer) => buffer.describe_value(),
43        }
44    }
45
46    pub fn is_valid(&self) -> bool {
47        true
48    }
49
50    pub fn to_bytes(&self) -> [u8; 256] {
51        self.value()
52    }
53}
54
55impl fmt::Display for NullableBuffer {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        write!(
58            f,
59            "{}",
60            match self {
61                Self::None => self.describe_value(),
62                Self::Some(buffer) => buffer.to_string(),
63            }
64        )
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn value_zero() {
74        let value = [0; 256];
75
76        let sut: NullableBuffer = (0..256).map(|_| 0).collect::<Vec<_>>().try_into().unwrap();
77
78        assert_eq!(sut, NullableBuffer::None);
79        assert_eq!(sut, value.into());
80        assert_eq!(sut.value(), value);
81        assert_eq!(sut.describe_value(), "VAZIO");
82        assert!(sut.is_valid());
83        assert_eq!(sut.to_bytes(), value);
84        assert_eq!(sut.to_string(), "VAZIO");
85    }
86
87    #[test]
88    fn value_some_bytes() {
89        let mut value = [0; 256];
90        for i in 0..8 {
91            value[i as usize] = i;
92        }
93        let value = value;
94
95        let sut: NullableBuffer = value.into();
96
97        assert_eq!(sut, NullableBuffer::Some(Box::new(value.into())));
98        assert_eq!(sut, value.into());
99        assert_eq!(sut.value(), value);
100        assert_eq!(sut.describe_value(), "len=8");
101        assert!(sut.is_valid());
102        assert_eq!(sut.to_bytes(), value);
103        assert_eq!(sut.to_string(), "blob [len=8]");
104    }
105
106    #[test]
107    fn value_full() {
108        let value: [u8; 256] = (0..=255).collect::<Vec<_>>().try_into().unwrap();
109
110        let sut: NullableBuffer = (0..=255).collect::<Vec<_>>().try_into().unwrap();
111
112        assert_eq!(sut, NullableBuffer::Some(Box::new(value.into())));
113        assert_eq!(sut, value.into());
114        assert_eq!(sut.value(), value);
115        assert_eq!(sut.describe_value(), "len=256");
116        assert!(sut.is_valid());
117        assert_eq!(sut.to_bytes(), value);
118        assert_eq!(sut.to_string(), "blob [len=256]");
119    }
120
121    #[test]
122    fn fail_on_short_vec() {
123        let value: Vec<_> = (0..255).map(|_| 0).collect();
124
125        TryInto::<NullableBuffer>::try_into(value).unwrap_err();
126    }
127}