rmesh/
strings.rs

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}