1use crate::internal_prelude::v1::*;
2
3use crate::types_bits::ByteArray;
4
5pub trait PackedStruct where Self: Sized {
13 type ByteArray : ByteArray;
15
16 fn pack(&self) -> PackingResult<Self::ByteArray>;
18 fn unpack(src: &Self::ByteArray) -> PackingResult<Self>;
20}
21
22pub trait PackedStructInfo {
24 fn packed_bits() -> usize;
26}
27
28pub trait PackedStructSlice where Self: Sized {
30 fn pack_to_slice(&self, output: &mut [u8]) -> PackingResult<()>;
32 fn unpack_from_slice(src: &[u8]) -> PackingResult<Self>;
34 fn packed_bytes_size(opt_self: Option<&Self>) -> PackingResult<usize>;
36
37 #[cfg(any(feature="alloc", feature="std"))]
38 fn pack_to_vec(&self) -> PackingResult<Vec<u8>> {
39 let size = Self::packed_bytes_size(Some(self))?;
40 let mut buf = vec![0; size];
41 self.pack_to_slice(&mut buf)?;
42 Ok(buf)
43 }
44}
45
46#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
47#[derive(Debug, Copy, Clone, PartialEq, Eq)]
48pub enum PackingError {
50 InvalidValue,
51 BitsError,
52 BufferTooSmall,
53 NotImplemented,
54 InstanceRequiredForSize,
55 MoreThanOneDynamicType,
56 BufferSizeMismatch { expected: usize, actual: usize },
57 BufferModMismatch { actual_size: usize, modulo_required: usize },
58 SliceIndexingError { slice_len: usize },
59 InternalError
60}
61
62impl crate::Display for PackingError {
63 fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
64 write!(f, "{:?}", self)
65 }
66}
67
68#[cfg(feature="std")]
69impl ::std::error::Error for PackingError {
70 fn description(&self) -> &str {
71 match *self {
72 PackingError::InvalidValue => "Invalid value",
73 PackingError::BitsError => "Bits error",
74 PackingError::BufferTooSmall => "Buffer too small",
75 PackingError::BufferSizeMismatch { .. } => "Buffer size mismatched",
76 PackingError::NotImplemented => "Not implemented",
77 PackingError::InstanceRequiredForSize => "This structure's packing size can't be determined statically, an instance is required.",
78 PackingError::BufferModMismatch { .. } => "The structure's size is not a multiple of the item's size",
79 PackingError::SliceIndexingError { .. } => "Failed to index into a slice",
80 PackingError::MoreThanOneDynamicType => "Only one dynamically sized type is supported in the tuple",
81 PackingError::InternalError => "Internal error"
82 }
83 }
84}
85
86impl From<PackingError> for crate::fmt::Error {
87 fn from(_: PackingError) -> Self {
88 Self
89 }
90}
91
92pub type PackingResult<T> = Result<T, PackingError>;