binja/lib.rs
1mod par;
2mod ser;
3
4pub mod config;
5pub mod containers;
6pub mod error;
7
8pub use par::{BinaryParse, parser::BinaryParser};
9pub use ser::{BinarySerialize, serializer::BinarySerializer};
10
11use crate::error::Result;
12use bytes::BytesMut;
13use config::Config;
14
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17
18#[cfg(feature = "derive")]
19pub use binja_derive::{BinaryParse, BinarySerialize};
20
21/// Serializes a given value into a binary format using the default configuration.
22///
23/// # Default Configuration
24/// - **Optional Strategy**: Tagged (uses a single byte to indicate `Some` or `None`)
25/// - **Endianness**: Little-endian
26/// - **Limit**: No size limit
27/// - **Container Length**: 4 bytes (used to encode the length of sequences, strings, etc.)
28///
29/// # Parameters
30/// - `value`: A reference to the value to be serialized. The value must implement the `Serialize` trait.
31///
32/// # Returns
33/// - `Ok(BytesMut)`: The serialized binary representation of the value.
34/// - `Err(Error)`: An error if serialization fails or exceeds the configured limit.
35///
36/// # Example
37/// ```rust
38/// use binja::{to_bytes, BinarySerialize};
39///
40/// #[derive(BinarySerialize)]
41/// struct Example {
42/// field1: u32,
43/// field2: Option<u32>,
44/// }
45///
46/// let value = Example {
47/// field1: 42,
48/// field2: Some(7),
49/// };
50///
51/// let serialized = to_bytes(&value).unwrap().to_vec();
52/// assert_eq!(serialized, vec![0x2A, 0x0, 0x0, 0x0, 0x1, 0x7, 0x0, 0x0, 0x0]);
53/// ```
54pub fn to_bytes<T>(value: &T) -> Result<BytesMut>
55where
56 T: BinarySerialize,
57{
58 to_bytes_with_config(value, Config::default())
59}
60
61/// See [`to_bytes`].
62#[cfg(feature = "serde")]
63pub fn serde_to_bytes<T>(value: &T) -> Result<BytesMut>
64where
65 T: Serialize,
66{
67 serde_to_bytes_with_config(value, Config::default())
68}
69
70/// Serializes a given value into a binary format using a custom configuration.
71///
72/// # Parameters
73/// - `value`: A reference to the value to be serialized. The value must implement the `Serialize` trait.
74/// - `config`: A `Config` object specifying the serialization settings (e.g., endianness, optional strategy, etc.).
75///
76/// # Returns
77/// - `Ok(BytesMut)`: The serialized binary representation of the value.
78/// - `Err(Error)`: An error if serialization fails or exceeds the configured limit.
79///
80/// # Example
81/// ```rust
82/// use binja::{to_bytes_with_config, BinarySerialize};
83/// use binja::config::{Config, EndiannessStrategy, OptionalStrategy};
84///
85/// #[derive(BinarySerialize)]
86/// struct Example {
87/// field1: u32,
88/// field2: Option<u32>,
89/// }
90///
91/// let config = Config {
92/// endianness_strategy: EndiannessStrategy::Big,
93/// optional_strategy: OptionalStrategy::Tagged,
94/// ..Default::default()
95/// };
96///
97/// let value = Example {
98/// field1: 42,
99/// field2: Some(7),
100/// };
101///
102/// let serialized = to_bytes_with_config(&value, config).unwrap().to_vec();
103/// assert_eq!(serialized, vec![0x00, 0x00, 0x00, 0x2A, 0x01, 0x00, 0x00, 0x00, 0x07]);
104/// ```
105pub fn to_bytes_with_config<T>(value: &T, config: Config) -> Result<BytesMut>
106where
107 T: BinarySerialize,
108{
109 let mut serializer = BinarySerializer::new(config);
110 value.binary_serialize(&mut serializer)?;
111 Ok(serializer.output())
112}
113
114/// See [`to_bytes_with_config`].
115#[cfg(feature = "serde")]
116pub fn serde_to_bytes_with_config<T>(value: &T, config: Config) -> Result<BytesMut>
117where
118 T: Serialize,
119{
120 let mut ser = BinarySerializer::new(config);
121 value.serialize(&mut ser)?;
122 Ok(ser.output())
123}
124
125/// Deserializes a binary slice into a value of type `T` using the default configuration.
126///
127/// # Default Configuration
128/// - **Optional Strategy**: Tagged (uses a single byte to indicate `Some` or `None`)
129/// - **Endianness**: Little-endian
130/// - **Limit**: No size limit
131/// - **Container Length**: 4 bytes (used to decode the length of sequences, strings, etc.)
132///
133/// # Parameters
134/// - `bytes`: The binary slice to deserialize. Must represent a valid serialized value of type `T`.
135///
136/// # Returns
137/// - `Ok((T, usize))`: The deserialized value and the number of bytes read.
138/// - `Err(Error)`: If deserialization fails or the input is invalid.
139///
140/// # Example
141/// ```rust
142/// use binja::{from_bytes, BinaryParse};
143///
144/// #[derive(BinaryParse, PartialEq, Debug)]
145/// struct Example {
146/// field1: u32,
147/// field2: Option<u32>,
148/// }
149///
150/// let bytes = vec![0x2A, 0x0, 0x0, 0x0, 0x1, 0x7, 0x0, 0x0, 0x0];
151/// let (value, size): (Example, usize) = from_bytes(&bytes).unwrap();
152/// assert_eq!(
153/// value,
154/// Example {
155/// field1: 42,
156/// field2: Some(7),
157/// }
158/// );
159/// assert_eq!(size, 0);
160/// ```
161pub fn from_bytes<T>(bytes: &[u8]) -> Result<(T, usize)>
162where
163 T: BinaryParse,
164{
165 from_bytes_with_config(bytes, Config::default())
166}
167
168/// See [`from_bytes`].
169#[cfg(feature = "serde")]
170pub fn serde_from_bytes<'a, T>(bytes: &'a [u8]) -> Result<(T, usize)>
171where
172 T: Deserialize<'a>,
173{
174 serde_from_bytes_with_config(bytes, Config::default())
175}
176
177/// Deserializes a binary slice into a value of type `T` using a custom configuration.
178///
179/// # Parameters
180/// - `bytes`: The binary slice to deserialize. Must represent a valid serialized value of type `T`.
181/// - `config`: The `Config` specifying deserialization settings (endianness, optional strategy, etc.).
182///
183/// # Returns
184/// - `Ok((T, usize))`: The deserialized value and the number of bytes read.
185/// - `Err(Error)`: If deserialization fails or the input is invalid.
186///
187/// # Example
188/// ```rust
189/// use binja::{from_bytes_with_config, BinaryParse};
190/// use binja::config::{Config, EndiannessStrategy, OptionalStrategy};
191///
192/// #[derive(BinaryParse, PartialEq, Debug)]
193/// struct Example {
194/// field1: u32,
195/// field2: Option<u32>,
196/// }
197///
198/// let config = Config {
199/// endianness_strategy: EndiannessStrategy::Big,
200/// optional_strategy: OptionalStrategy::Tagged,
201/// ..Default::default()
202/// };
203///
204/// let bytes = vec![0x00, 0x00, 0x00, 0x2A, 0x01, 0x00, 0x00, 0x00, 0x07];
205/// let (value, size): (Example, usize) = from_bytes_with_config(&bytes, config).unwrap();
206/// assert_eq!(
207/// value,
208/// Example {
209/// field1: 42,
210/// field2: Some(7),
211/// }
212/// );
213/// assert_eq!(size, 0);
214/// ```
215pub fn from_bytes_with_config<T>(bytes: &[u8], config: Config) -> Result<(T, usize)>
216where
217 T: BinaryParse,
218{
219 let mut deserializer = BinaryParser::new(bytes, config);
220
221 let v = T::binary_parse(&mut deserializer)?;
222 let size = deserializer.size();
223
224 Ok((v, size))
225}
226
227/// See [`from_bytes_with_config`].
228#[cfg(feature = "serde")]
229pub fn serde_from_bytes_with_config<'a, T>(bytes: &'a [u8], config: Config) -> Result<(T, usize)>
230where
231 T: Deserialize<'a>,
232{
233 let mut deserializer = BinaryParser::new(bytes, config);
234
235 let v = T::deserialize(&mut deserializer)?;
236 let size = deserializer.size();
237
238 Ok((v, size))
239}
240
241#[macro_export]
242macro_rules! bit {
243 ($bits:expr) => {
244 (1 << $bits)
245 };
246}
247
248#[macro_export]
249macro_rules! bit_mask {
250 ($bits:expr) => {
251 ((1 << $bits) - 1)
252 };
253}