msg_tool\utils/
struct_pack.rs1use crate::types::Encoding;
3use anyhow::Result;
4use msg_tool_macro::struct_unpack_impl_for_num;
5use std::any::Any;
6use std::io::{Read, Seek, Write};
7
8pub trait StructUnpack: Sized {
10 fn unpack<R: Read + Seek>(
17 reader: &mut R,
18 big: bool,
19 encoding: Encoding,
20 info: &Option<Box<dyn Any>>,
21 ) -> Result<Self>;
22}
23
24pub trait StructPack: Sized {
26 fn pack<W: Write>(
33 &self,
34 writer: &mut W,
35 big: bool,
36 encoding: Encoding,
37 info: &Option<Box<dyn Any>>,
38 ) -> Result<()>;
39}
40
41impl<T: StructPack> StructPack for Vec<T> {
42 fn pack<W: Write>(
43 &self,
44 writer: &mut W,
45 big: bool,
46 encoding: Encoding,
47 info: &Option<Box<dyn Any>>,
48 ) -> Result<()> {
49 for item in self {
50 item.pack(writer, big, encoding, info)?;
51 }
52 Ok(())
53 }
54}
55
56struct_unpack_impl_for_num!(u8);
57struct_unpack_impl_for_num!(u16);
58struct_unpack_impl_for_num!(u32);
59struct_unpack_impl_for_num!(u64);
60struct_unpack_impl_for_num!(u128);
61struct_unpack_impl_for_num!(i8);
62struct_unpack_impl_for_num!(i16);
63struct_unpack_impl_for_num!(i32);
64struct_unpack_impl_for_num!(i64);
65struct_unpack_impl_for_num!(i128);
66struct_unpack_impl_for_num!(f32);
67struct_unpack_impl_for_num!(f64);
68
69impl StructUnpack for bool {
70 fn unpack<R: Read + Seek>(
71 reader: &mut R,
72 _big: bool,
73 _encoding: Encoding,
74 _info: &Option<Box<dyn Any>>,
75 ) -> Result<Self> {
76 let mut buf = [0u8; 1];
77 reader.read_exact(&mut buf)?;
78 Ok(buf[0] != 0)
79 }
80}
81
82impl StructPack for bool {
83 fn pack<W: Write>(
84 &self,
85 writer: &mut W,
86 _big: bool,
87 _encoding: Encoding,
88 _info: &Option<Box<dyn Any>>,
89 ) -> Result<()> {
90 writer.write_all(&[if *self { 1 } else { 0 }])?;
91 Ok(())
92 }
93}
94
95impl<T: StructPack> StructPack for Option<T> {
96 fn pack<W: Write>(
97 &self,
98 writer: &mut W,
99 big: bool,
100 encoding: Encoding,
101 info: &Option<Box<dyn Any>>,
102 ) -> Result<()> {
103 if let Some(value) = self {
104 value.pack(writer, big, encoding, info)?;
105 }
106 Ok(())
107 }
108}
109
110impl<T: StructUnpack> StructUnpack for Option<T> {
111 fn unpack<R: Read + Seek>(
112 reader: &mut R,
113 big: bool,
114 encoding: Encoding,
115 info: &Option<Box<dyn Any>>,
116 ) -> Result<Self> {
117 let value = T::unpack(reader, big, encoding, info)?;
118 Ok(Some(value))
119 }
120}
121
122impl<const T: usize> StructPack for [u8; T] {
123 fn pack<W: Write>(
124 &self,
125 writer: &mut W,
126 _big: bool,
127 _encoding: Encoding,
128 _info: &Option<Box<dyn Any>>,
129 ) -> Result<()> {
130 writer.write_all(self)?;
131 Ok(())
132 }
133}
134
135impl<const T: usize> StructUnpack for [u8; T] {
136 fn unpack<R: Read + Seek>(
137 reader: &mut R,
138 _big: bool,
139 _encoding: Encoding,
140 _info: &Option<Box<dyn Any>>,
141 ) -> Result<Self> {
142 let mut buf = [0u8; T];
143 reader.read_exact(&mut buf)?;
144 Ok(buf)
145 }
146}