rsfn_file/header/fields/
nullable_buffer.rs1use std::fmt;
2
3use super::Buffer;
4
5#[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}