1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// SPDX-License-Identifier: MIT
// Copyright 2024 IROX Contributors
//
//!
//! A very simple 'Struct' library that provides a single trait. This is intended to be most
//! generally used in concert with [`irox_structs_derive`] to generate the impls.
//!
//! A Struct is a linear sequence in memory of serialized bytes - serialized in the order the
//! fields are present in the struct with no adjacency or packing.
//!
//! ## Strict Sizing
//! By default, [`irox_structs_derive`] will allow variably sized types like [`String`] and [`Vec<u8>`].
//! If you know you don't need/use these, apply a `#[strict_sizing]` attribute, and the generator
//! will add a `pub const STRUCT_SIZE: usize` to the struct
//!
//! ## Choosing Endianness:
//! Apply either the `#[big_endian]` or `#[little_endian]` attributes when deriving [`Struct`] and
//! it will use the appropriate serializers. If not specified, it defaults to big endian.
//!
//! ### Example Big Endian:
//! ```
//! use irox_structs::Struct;
//! use irox_bits::Error;
//!
//! #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Struct)]
//! #[strict_sizing]
//! pub struct UdpHeader {
//! source_port: u16,
//! dest_port: u16,
//! length: u16,
//! checksum: u16,
//! }
//!
//! pub fn main() -> Result<(), Error>{
//! assert_eq!(8, UdpHeader::STRUCT_SIZE);
//!
//! let header = UdpHeader {
//! source_port: 0x0064,
//! dest_port: 0x0400,
//! length: 0x1388,
//! checksum: 0x01C2,
//! };
//! let mut output_buf: Vec<u8> = Vec::new();
//!
//! header.write_to(&mut output_buf)?;
//! assert_eq!(output_buf.len(), 8);
//! assert_eq!(&[0x00u8, 0x64, 0x04, 0x00, 0x13, 0x88, 0x01, 0xC2],
//! output_buf.as_slice());
//!
//! let parsed = UdpHeader::parse_from(&mut output_buf.as_slice())?;
//! assert_eq!(header, parsed);
//! Ok(())
//! }
//! ```
//! ### Example Little Endian:
//! ```
//! use irox_structs::Struct;
//! use irox_bits::Error;
//!
//! #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Struct)]
//! #[little_endian]
//! #[strict_sizing]
//! pub struct UdpHeader {
//! source_port: u16,
//! dest_port: u16,
//! length: u16,
//! checksum: u16,
//! }
//!
//! pub fn main() -> Result<(), Error>{
//! assert_eq!(8, UdpHeader::STRUCT_SIZE);
//! let header = UdpHeader {
//! source_port: 0x0064,
//! dest_port: 0x0400,
//! length: 0x1388,
//! checksum: 0x01C2,
//! };
//! let mut output_buf: Vec<u8> = Vec::new();
//!
//! header.write_to(&mut output_buf)?;
//! assert_eq!(output_buf.len(), 8);
//! assert_eq!(&[0x64u8, 0x00, 0x00, 0x04, 0x88, 0x13, 0xC2, 0x01],
//! output_buf.as_slice());
//!
//! let parsed = UdpHeader::parse_from(&mut output_buf.as_slice())?;
//! assert_eq!(header, parsed);
//! Ok(())
//! }
//! ```
pub use ;
pub use *;
extern crate alloc;
///
/// A struct is a series of bytes in memory, serialized in the order that the
/// fields are present in the struct.
///
/// Generally speaking, you shouldn't need to implement this, unless you need
/// some custom encoding. It's intended to be used with [`irox_structs_derive`] to automatically
/// generate the impl.