1use std::fmt;
2
3use binrw::{BinRead, BinWrite};
4
5#[derive(BinRead, BinWrite, Clone, Eq, PartialEq, Default)]
6pub struct FixedLengthString {
7 pub len: u32,
8 #[br(count = len)]
9 pub values: Vec<u8>,
10}
11
12impl fmt::Debug for FixedLengthString {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 write!(f, "FixedLengthString(\"")?;
15 write!(f, "{}", String::from_utf8(self.values.clone()).unwrap())?;
16 write!(f, "\")")
17 }
18}
19
20impl From<&str> for FixedLengthString {
21 fn from(s: &str) -> Self {
22 let values = s.as_bytes().to_vec();
23 Self {
24 len: values.len() as u32,
25 values,
26 }
27 }
28}
29
30impl From<String> for FixedLengthString {
31 fn from(s: String) -> Self {
32 let values = s.into_bytes();
33 Self {
34 len: values.len() as u32,
35 values,
36 }
37 }
38}
39
40impl From<FixedLengthString> for String {
41 fn from(value: FixedLengthString) -> Self {
42 String::from_utf8(value.values).unwrap()
43 }
44}
45
46impl From<&FixedLengthString> for String {
47 fn from(value: &FixedLengthString) -> Self {
48 String::from_utf8(value.values.clone()).unwrap()
49 }
50}
51
52#[derive(Clone, Eq, PartialEq, Default, Debug)]
53pub struct ThreeTypeString(pub Vec<u8>);
54
55impl BinRead for ThreeTypeString {
56 type Args<'a> = ();
57
58 fn read_options<R: std::io::Read + std::io::Seek>(
59 reader: &mut R,
60 endian: binrw::Endian,
61 _args: Self::Args<'_>,
62 ) -> binrw::BinResult<Self> {
63 let len = <u32>::read_options(reader, endian, ())?;
64
65 let mut values = vec![];
66
67 for _ in 0..len {
68 let val = <u8>::read_options(reader, endian, ())?;
69 values.push(val);
70 }
71
72 let string = String::from_utf8(values).unwrap();
73 let stuff: Vec<_> = string
74 .split(' ')
75 .map(|c| c.parse::<u8>().unwrap())
76 .collect();
77
78 Ok(Self(stuff))
79 }
80}
81
82impl BinWrite for ThreeTypeString {
83 type Args<'a> = ();
84
85 fn write_options<W: std::io::Write + std::io::Seek>(
86 &self,
87 writer: &mut W,
88 endian: binrw::Endian,
89 _args: Self::Args<'_>,
90 ) -> binrw::BinResult<()> {
91 let string = self
92 .0
93 .iter()
94 .map(|num| num.to_string())
95 .collect::<Vec<String>>()
96 .join(" ");
97
98 let bytes = string.into_bytes();
99 let len = bytes.len() as u32;
100
101 len.write_options(writer, endian, ())?;
102 writer.write_all(&bytes[..])?;
103
104 Ok(())
105 }
106}
107
108impl From<Vec<u8>> for ThreeTypeString {
109 fn from(value: Vec<u8>) -> Self {
110 Self(value)
111 }
112}
113
114impl From<[u8; 3]> for ThreeTypeString {
115 fn from(value: [u8; 3]) -> Self {
116 Self(value.to_vec())
117 }
118}