binary_mirror/
lib.rs

1use std::fmt;
2
3#[derive(Debug)]
4pub struct BytesSizeError {
5    pub(crate) expected: usize,
6    pub(crate) actual: usize,
7    pub(crate) bytes: String,
8}
9
10impl fmt::Display for BytesSizeError {
11    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12        write!(
13            f,
14            "bytes size mismatch: expected {} bytes but got {} bytes, content: \"{}\"",
15            self.expected, self.actual, self.bytes
16        )
17    }
18}
19
20impl std::error::Error for BytesSizeError {}
21
22impl BytesSizeError {
23    pub fn new(expected: usize, actual: usize, bytes: String) -> Self {
24        Self {
25            expected,
26            actual,
27            bytes,
28        }
29    }
30}
31
32pub fn to_hex_repr(bytes: &[u8]) -> String {
33    bytes.iter().map(|b| format!("0x{:02x}", b)).collect::<Vec<_>>().join(", ")
34}
35
36pub fn to_bytes_repr(bytes: &[u8]) -> String {
37    bytes.iter().map(|&b| {
38        match b {
39            0x0A => "\\n".to_string(),
40            0x0D => "\\r".to_string(),
41            0x09 => "\\t".to_string(),
42            0x20..=0x7E => (b as char).to_string(),
43            _ => format!("\\x{:02x}", b),
44        }
45    }).collect::<Vec<String>>().join("")
46}
47
48#[derive(Debug, Clone)]
49pub struct FieldSpec {
50    pub offset: usize,
51    pub limit: usize,
52    pub size: usize,
53}
54
55pub trait FromBytes: Sized {
56    /// Get the size of the struct in bytes
57    const SIZE: usize;
58
59    /// Create a new instance from bytes
60    /// Returns Err if the bytes length doesn't match the struct size
61    fn from_bytes(bytes: &[u8]) -> Result<&Self, BytesSizeError>;
62}
63
64pub trait ToBytes {
65    /// Convert the struct to its binary representation
66    fn to_bytes(&self) -> &[u8];
67    
68    /// Convert the struct to an owned Vec<u8>
69    fn to_bytes_owned(&self) -> Vec<u8> {
70        self.to_bytes().to_vec()
71    }
72}
73
74pub trait ToNative {
75    type Native;
76    
77    /// Convert to native type
78    fn to_native(&self) -> Self::Native;
79}
80
81pub trait FromNative<T> {
82    /// Create from native type
83    fn from_native(native: &T) -> Self;
84}
85
86pub trait NativeStructCode {
87    /// Get the native struct code as a string
88    fn native_struct_code() -> String;
89}