aboutsummaryrefslogtreecommitdiff
path: root/src/structs
diff options
context:
space:
mode:
Diffstat (limited to 'src/structs')
-rw-r--r--src/structs/error.rs29
-rw-r--r--src/structs/mod.rs13
-rw-r--r--src/structs/ser.rs339
-rw-r--r--src/structs/settings.rs110
-rw-r--r--src/structs/tests.rs88
5 files changed, 576 insertions, 3 deletions
diff --git a/src/structs/error.rs b/src/structs/error.rs
new file mode 100644
index 0000000..b9d765d
--- /dev/null
+++ b/src/structs/error.rs
@@ -0,0 +1,29 @@
1use crate::{ArchiveError, ArchiveResult};
2use std::error::Error;
3use std::fmt::Display;
4
5pub type StructResult<T> = ArchiveResult<T, StructError>;
6
7#[derive(Debug)]
8pub enum StructError {
9 IncorrectEnumVariant,
10}
11
12impl From<StructError> for ArchiveError<StructError> {
13 fn from(value: StructError) -> Self {
14 Self::Archivator {
15 module: "Struct serializer".to_string(),
16 error: value,
17 }
18 }
19}
20
21impl Display for StructError {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 match self {
24 StructError::IncorrectEnumVariant => write!(f, "Can't cast enum variant type"),
25 }
26 }
27}
28
29impl Error for StructError {}
diff --git a/src/structs/mod.rs b/src/structs/mod.rs
index d7e9daa..feb37dd 100644
--- a/src/structs/mod.rs
+++ b/src/structs/mod.rs
@@ -1,2 +1,11 @@
1mod de; 1pub mod de;
2mod ser; 2mod error;
3pub mod ser;
4mod settings;
5
6pub use error::{StructError, StructResult};
7pub use ser::ArchiveSerializer;
8pub use settings::{ByteOrder, Settings, VariantIndexType};
9
10#[cfg(test)]
11mod tests;
diff --git a/src/structs/ser.rs b/src/structs/ser.rs
index a3fe291..8aa95a5 100644
--- a/src/structs/ser.rs
+++ b/src/structs/ser.rs
@@ -1,6 +1,343 @@
1use crate::structs::{Settings, StructError, StructResult};
1use crate::ArchiveError; 2use crate::ArchiveError;
2use serde::{ser, Serialize}; 3use serde::{ser, Serialize};
3 4
4pub struct ArchiveSerializer { 5pub struct ArchiveSerializer {
5 bin: Vec<u8>, 6 bytes: Vec<u8>,
7 settings: Settings,
8}
9
10impl ArchiveSerializer {
11 pub fn new(settings: Settings) -> Self {
12 Self {
13 bytes: Vec::new(),
14 settings,
15 }
16 }
17
18 pub fn to_bytes(self) -> Vec<u8> {
19 self.bytes
20 }
21}
22
23impl ser::Serializer for &mut ArchiveSerializer {
24 type Ok = ();
25 type Error = ArchiveError<StructError>;
26
27 type SerializeSeq = Self;
28 type SerializeTuple = Self;
29 type SerializeTupleStruct = Self;
30 type SerializeTupleVariant = Self;
31 type SerializeMap = Self;
32 type SerializeStruct = Self;
33 type SerializeStructVariant = Self;
34
35 fn serialize_bool(self, v: bool) -> StructResult<()> {
36 self.bytes.push(v as u8);
37 Ok(())
38 }
39
40 fn serialize_i8(self, v: i8) -> StructResult<()> {
41 self.bytes.push(v as u8);
42 Ok(())
43 }
44
45 fn serialize_i16(self, v: i16) -> StructResult<()> {
46 self.bytes.append(&mut self.settings.byte_order.i16(v));
47 Ok(())
48 }
49
50 fn serialize_i32(self, v: i32) -> StructResult<()> {
51 self.bytes.append(&mut self.settings.byte_order.i32(v));
52 Ok(())
53 }
54
55 fn serialize_i64(self, v: i64) -> StructResult<()> {
56 self.bytes.append(&mut self.settings.byte_order.i64(v));
57 Ok(())
58 }
59
60 fn serialize_u8(self, v: u8) -> StructResult<()> {
61 self.bytes.push(v);
62 Ok(())
63 }
64
65 fn serialize_u16(self, v: u16) -> StructResult<()> {
66 self.bytes.append(&mut self.settings.byte_order.u16(v));
67 Ok(())
68 }
69
70 fn serialize_u32(self, v: u32) -> StructResult<()> {
71 self.bytes.append(&mut self.settings.byte_order.u32(v));
72 Ok(())
73 }
74
75 fn serialize_u64(self, v: u64) -> StructResult<()> {
76 self.bytes.append(&mut self.settings.byte_order.u64(v));
77 Ok(())
78 }
79
80 fn serialize_f32(self, v: f32) -> StructResult<()> {
81 self.bytes.append(&mut self.settings.byte_order.f32(v));
82 Ok(())
83 }
84
85 fn serialize_f64(self, v: f64) -> StructResult<()> {
86 self.bytes.append(&mut self.settings.byte_order.f64(v));
87 Ok(())
88 }
89
90 fn serialize_char(self, v: char) -> StructResult<()> {
91 self.bytes.push(v as u8);
92 Ok(())
93 }
94
95 fn serialize_str(self, v: &str) -> StructResult<()> {
96 self.bytes.append(&mut v.as_bytes().to_vec());
97 Ok(())
98 }
99
100 fn serialize_bytes(self, v: &[u8]) -> StructResult<()> {
101 self.bytes.append(&mut v.to_vec());
102 Ok(())
103 }
104
105 fn serialize_none(self) -> StructResult<()> {
106 Ok(())
107 }
108
109 fn serialize_some<T>(self, value: &T) -> StructResult<()>
110 where
111 T: ?Sized + Serialize,
112 {
113 value.serialize(self)
114 }
115
116 fn serialize_unit(self) -> StructResult<()> {
117 Ok(())
118 }
119
120 fn serialize_unit_struct(self, _name: &'static str) -> StructResult<()> {
121 self.serialize_unit()
122 }
123
124 fn serialize_unit_variant(
125 self,
126 _name: &'static str,
127 variant_index: u32,
128 _variant: &'static str,
129 ) -> StructResult<()> {
130 self.bytes.append(
131 &mut self
132 .settings
133 .variant_index_type
134 .cast(variant_index, &self.settings.byte_order)?,
135 );
136 Ok(())
137 }
138
139 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> StructResult<()>
140 where
141 T: ?Sized + Serialize,
142 {
143 value.serialize(self)
144 }
145
146 fn serialize_newtype_variant<T>(
147 self,
148 _name: &'static str,
149 variant_index: u32,
150 _variant: &'static str,
151 value: &T,
152 ) -> StructResult<()>
153 where
154 T: ?Sized + Serialize,
155 {
156 self.bytes.append(
157 &mut self
158 .settings
159 .variant_index_type
160 .cast(variant_index, &self.settings.byte_order)?,
161 );
162 value.serialize(self)
163 }
164
165 fn serialize_seq(self, _len: Option<usize>) -> StructResult<Self::SerializeSeq> {
166 Ok(self)
167 }
168
169 fn serialize_tuple(self, _len: usize) -> StructResult<Self::SerializeTuple> {
170 Ok(self)
171 }
172
173 fn serialize_tuple_struct(
174 self,
175 _name: &'static str,
176 _len: usize,
177 ) -> StructResult<Self::SerializeTupleStruct> {
178 Ok(self)
179 }
180
181 fn serialize_tuple_variant(
182 self,
183 _name: &'static str,
184 variant_index: u32,
185 _variant: &'static str,
186 _len: usize,
187 ) -> StructResult<Self::SerializeTupleVariant> {
188 self.bytes.append(
189 &mut self
190 .settings
191 .variant_index_type
192 .cast(variant_index, &self.settings.byte_order)?,
193 );
194 Ok(self)
195 }
196
197 fn serialize_map(self, _len: Option<usize>) -> StructResult<Self::SerializeMap> {
198 Ok(self)
199 }
200
201 fn serialize_struct(
202 self,
203 _name: &'static str,
204 _len: usize,
205 ) -> StructResult<Self::SerializeStruct> {
206 Ok(self)
207 }
208
209 fn serialize_struct_variant(
210 self,
211 _name: &'static str,
212 variant_index: u32,
213 _variant: &'static str,
214 _len: usize,
215 ) -> StructResult<Self::SerializeStructVariant> {
216 self.bytes.append(
217 &mut self
218 .settings
219 .variant_index_type
220 .cast(variant_index, &self.settings.byte_order)?,
221 );
222 Ok(self)
223 }
224}
225
226impl ser::SerializeSeq for &mut ArchiveSerializer {
227 type Ok = ();
228 type Error = ArchiveError<StructError>;
229
230 fn serialize_element<T>(&mut self, value: &T) -> StructResult<()>
231 where
232 T: ?Sized + Serialize,
233 {
234 value.serialize(&mut **self)
235 }
236
237 fn end(self) -> StructResult<()> {
238 Ok(())
239 }
240}
241
242impl ser::SerializeTuple for &mut ArchiveSerializer {
243 type Ok = ();
244 type Error = ArchiveError<StructError>;
245
246 fn serialize_element<T>(&mut self, value: &T) -> StructResult<()>
247 where
248 T: ?Sized + Serialize,
249 {
250 value.serialize(&mut **self)
251 }
252
253 fn end(self) -> StructResult<()> {
254 Ok(())
255 }
256}
257
258impl ser::SerializeTupleStruct for &mut ArchiveSerializer {
259 type Ok = ();
260 type Error = ArchiveError<StructError>;
261
262 fn serialize_field<T>(&mut self, value: &T) -> StructResult<()>
263 where
264 T: ?Sized + Serialize,
265 {
266 value.serialize(&mut **self)
267 }
268
269 fn end(self) -> StructResult<()> {
270 Ok(())
271 }
272}
273
274impl ser::SerializeTupleVariant for &mut ArchiveSerializer {
275 type Ok = ();
276 type Error = ArchiveError<StructError>;
277
278 fn serialize_field<T>(&mut self, value: &T) -> StructResult<()>
279 where
280 T: ?Sized + Serialize,
281 {
282 value.serialize(&mut **self)
283 }
284
285 fn end(self) -> StructResult<()> {
286 Ok(())
287 }
288}
289
290impl ser::SerializeMap for &mut ArchiveSerializer {
291 type Ok = ();
292 type Error = ArchiveError<StructError>;
293
294 fn serialize_key<T>(&mut self, key: &T) -> StructResult<()>
295 where
296 T: ?Sized + Serialize,
297 {
298 key.serialize(&mut **self)
299 }
300
301 fn serialize_value<T>(&mut self, value: &T) -> StructResult<()>
302 where
303 T: ?Sized + Serialize,
304 {
305 value.serialize(&mut **self)
306 }
307
308 fn end(self) -> StructResult<()> {
309 Ok(())
310 }
311}
312
313impl ser::SerializeStruct for &mut ArchiveSerializer {
314 type Ok = ();
315 type Error = ArchiveError<StructError>;
316
317 fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> StructResult<()>
318 where
319 T: ?Sized + Serialize,
320 {
321 value.serialize(&mut **self)
322 }
323
324 fn end(self) -> StructResult<()> {
325 Ok(())
326 }
327}
328
329impl ser::SerializeStructVariant for &mut ArchiveSerializer {
330 type Ok = ();
331 type Error = ArchiveError<StructError>;
332
333 fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> StructResult<()>
334 where
335 T: ?Sized + Serialize,
336 {
337 value.serialize(&mut **self)
338 }
339
340 fn end(self) -> StructResult<()> {
341 Ok(())
342 }
6} 343}
diff --git a/src/structs/settings.rs b/src/structs/settings.rs
new file mode 100644
index 0000000..63c4d3a
--- /dev/null
+++ b/src/structs/settings.rs
@@ -0,0 +1,110 @@
1use crate::structs::{ArchiveSerializer, StructError, StructResult};
2use serde::Serialize;
3
4pub enum ByteOrder {
5 Le,
6 Be,
7 Ne,
8}
9
10pub enum VariantIndexType {
11 U8,
12 U16,
13 U32,
14 U64,
15 I8,
16 I16,
17 I32,
18 I64,
19}
20
21macro_rules! impl_byte_order {
22 ($($n:ident),+) => {
23 impl ByteOrder {$(
24 pub fn $n(&self, num: $n) -> Vec<u8> {
25 match self {
26 ByteOrder::Le => num.to_le_bytes().to_vec(),
27 ByteOrder::Be => num.to_be_bytes().to_vec(),
28 ByteOrder::Ne => num.to_ne_bytes().to_vec(),
29 }
30 }
31 )+}
32 };
33}
34impl_byte_order!(u8, u16, u32, u64, i8, i16, i32, i64, f32, f64);
35
36impl VariantIndexType {
37 pub fn cast(&self, num: u32, byte_order: &ByteOrder) -> StructResult<Vec<u8>> {
38 Ok(match self {
39 VariantIndexType::U8 => byte_order.u8(num
40 .try_into()
41 .map_err(|_| StructError::IncorrectEnumVariant)?),
42 VariantIndexType::U16 => byte_order.u16(
43 num.try_into()
44 .map_err(|_| StructError::IncorrectEnumVariant)?,
45 ),
46 VariantIndexType::U32 => byte_order.u32(
47 num.try_into()
48 .map_err(|_| StructError::IncorrectEnumVariant)?,
49 ),
50 VariantIndexType::U64 => byte_order.u64(
51 num.try_into()
52 .map_err(|_| StructError::IncorrectEnumVariant)?,
53 ),
54 VariantIndexType::I8 => byte_order.i8(num
55 .try_into()
56 .map_err(|_| StructError::IncorrectEnumVariant)?),
57 VariantIndexType::I16 => byte_order.i16(
58 num.try_into()
59 .map_err(|_| StructError::IncorrectEnumVariant)?,
60 ),
61 VariantIndexType::I32 => byte_order.i32(
62 num.try_into()
63 .map_err(|_| StructError::IncorrectEnumVariant)?,
64 ),
65 VariantIndexType::I64 => byte_order.i64(
66 num.try_into()
67 .map_err(|_| StructError::IncorrectEnumVariant)?,
68 ),
69 })
70 }
71}
72
73pub struct Settings {
74 pub(crate) byte_order: ByteOrder,
75 pub(crate) variant_index_type: VariantIndexType,
76}
77
78impl Settings {
79 pub fn new(byte_order: ByteOrder, variant_index_type: VariantIndexType) -> Self {
80 Self {
81 byte_order,
82 variant_index_type,
83 }
84 }
85
86 pub fn byte_order(mut self, order: ByteOrder) -> Self {
87 self.byte_order = order;
88 self
89 }
90
91 pub fn variant_index_type(mut self, index_type: VariantIndexType) -> Self {
92 self.variant_index_type = index_type;
93 self
94 }
95
96 pub fn serialize(self, object: &impl Serialize) -> StructResult<Vec<u8>> {
97 let mut serializer = ArchiveSerializer::new(self);
98 object.serialize(&mut serializer)?;
99 Ok(serializer.to_bytes())
100 }
101}
102
103impl Default for Settings {
104 fn default() -> Self {
105 Self {
106 byte_order: ByteOrder::Le,
107 variant_index_type: VariantIndexType::U32,
108 }
109 }
110}
diff --git a/src/structs/tests.rs b/src/structs/tests.rs
new file mode 100644
index 0000000..0fa5347
--- /dev/null
+++ b/src/structs/tests.rs
@@ -0,0 +1,88 @@
1use crate::structs::{ByteOrder, Settings, VariantIndexType};
2use serde::Serialize;
3
4#[derive(Serialize)]
5struct Struct<'a> {
6 u8: u8,
7 u16: u16,
8 u32: u32,
9 u64: u64,
10 u8arr: [u8; 3],
11 tuple: (u16, u8),
12 str: &'a str,
13}
14
15#[derive(Serialize)]
16enum Enum<'a> {
17 Unit,
18 Type(u16),
19 Tuple(u16, &'a str),
20 Struct { u32: u32, u64: u64 },
21}
22
23#[test]
24fn struct_serialize_test() {
25 let object = Struct {
26 u8: 42,
27 u16: 26,
28 u32: 69,
29 u64: 11,
30 u8arr: [37, 74, 111],
31 tuple: (24, 13),
32 str: "yes",
33 };
34
35 let bytes = Settings::default()
36 .byte_order(ByteOrder::Le)
37 .serialize(&object)
38 .unwrap();
39 assert_eq!(
40 bytes,
41 //u8|-u16--|----u32-----|----------u64-----------|[0]-[1]--[2]|.0 --.1---|-y----e----s|
42 [42, 26, 0, 69, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 37, 74, 111, 24, 0, 13, 121, 101, 115]
43 );
44
45 let bytes = Settings::default()
46 .byte_order(ByteOrder::Be)
47 .serialize(&object)
48 .unwrap();
49 assert_eq!(
50 bytes,
51 //u8|-u16--|----u32-----|----------u64-----------|[0]-[1]--[2]|.0 --.1---|-y----e----s|
52 [42, 0, 26, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 11, 37, 74, 111, 0, 24, 13, 121, 101, 115]
53 );
54}
55
56#[test]
57fn enum_serialize_test() {
58 let bytes = Settings::default()
59 .byte_order(ByteOrder::Le)
60 .variant_index_type(VariantIndexType::U8)
61 .serialize(&Enum::Unit)
62 .unwrap();
63 assert_eq!(bytes, [0]);
64
65 let bytes = Settings::default()
66 .byte_order(ByteOrder::Le)
67 .variant_index_type(VariantIndexType::U16)
68 .serialize(&Enum::Type(42))
69 .unwrap();
70 assert_eq!(bytes, [1, 0, 42, 0]);
71
72 let bytes = Settings::default()
73 .byte_order(ByteOrder::Le)
74 .variant_index_type(VariantIndexType::U32)
75 .serialize(&Enum::Tuple(26, "yes"))
76 .unwrap();
77 assert_eq!(bytes, [2, 0, 0, 0, 26, 0, 121, 101, 115]);
78
79 let bytes = Settings::default()
80 .byte_order(ByteOrder::Be)
81 .variant_index_type(VariantIndexType::U64)
82 .serialize(&Enum::Struct { u32: 69, u64: 37 })
83 .unwrap();
84 assert_eq!(
85 bytes,
86 [0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 37]
87 );
88}