1use binrw::{BinRead, BinResult, BinWrite};
2
3pub struct FixedString<const N: usize>([u8; N]);
8
9impl<const N: usize> FixedString<N> {
10 pub fn new(bytes: [u8; N]) -> Self {
11 Self(bytes)
12 }
13}
14
15impl<const N: usize> Default for FixedString<N> {
16 fn default() -> Self {
17 Self([0u8; N])
18 }
19}
20
21impl<const N: usize> std::fmt::Display for FixedString<N> {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 let FixedString(bytes) = self;
24 f.write_str(String::from_utf8_lossy(bytes).as_ref())
25 }
26}
27
28impl<const N: usize> From<FixedString<N>> for String {
29 fn from(FixedString(bytes): FixedString<N>) -> Self {
30 String::from_utf8_lossy(&bytes).to_string()
31 }
32}
33
34impl<const N: usize> From<String> for FixedString<N> {
35 fn from(value: String) -> Self {
36 let mut bytes = [0u8; N];
37 bytes.copy_from_slice(&value.as_bytes()[..N]);
38 FixedString(bytes)
39 }
40}
41
42impl<const N: usize> BinRead for FixedString<N> {
43 type Args<'a> = ();
44
45 fn read_options<R: std::io::Read + std::io::Seek>(
46 reader: &mut R,
47 endian: binrw::Endian,
48 _args: Self::Args<'_>,
49 ) -> BinResult<Self> {
50 Ok(FixedString(<[u8; N]>::read_options(reader, endian, ())?))
51 }
52}
53
54impl<const N: usize> BinWrite for FixedString<N> {
55 type Args<'a> = ();
56
57 fn write_options<W: std::io::Write + std::io::Seek>(
58 &self,
59 writer: &mut W,
60 endian: binrw::Endian,
61 _args: Self::Args<'_>,
62 ) -> BinResult<()> {
63 let FixedString(bytes) = self;
64 bytes.write_options(writer, endian, ())
65 }
66}