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 const SIZE: usize;
58
59 fn from_bytes(bytes: &[u8]) -> Result<&Self, BytesSizeError>;
62}
63
64pub trait ToBytes {
65 fn to_bytes(&self) -> &[u8];
67
68 fn to_bytes_owned(&self) -> Vec<u8> {
70 self.to_bytes().to_vec()
71 }
72}
73
74pub trait ToNative {
75 type Native;
76
77 fn to_native(&self) -> Self::Native;
79}
80
81pub trait FromNative<T> {
82 fn from_native(native: &T) -> Self;
84}
85
86pub trait NativeStructCode {
87 fn native_struct_code() -> String;
89}