lightpack/
extra.rs

1//! Additional utilities.
2
3use byteorder::{LittleEndian, BigEndian, ByteOrder};
4
5use crate::{Size, Pack, Unpack, unpack::{Result, self}};
6
7/// A wrapper that always encodes the type as little endian.
8#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Copy)]
9pub struct LE<T>(pub T);
10
11/// A wrapper that always encodes the type as big endian.
12#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Copy)]
13pub struct BE<T>(pub T);
14
15impl<T> Size for LE<T> where T: Size {
16    const SIZE: usize = T::SIZE;
17}
18
19impl<T> Size for BE<T> where T: Size {
20    const SIZE: usize = T::SIZE;
21}
22
23impl<T> Pack for LE<T> where T: Pack {
24    fn pack<B>(&self, buffer: &mut [u8]) where B: ByteOrder {
25        self.0.pack::<LittleEndian>(buffer)
26    }
27}
28
29impl<T> Pack for BE<T> where T: Pack {
30    fn pack<B>(&self, buffer: &mut [u8]) where B: ByteOrder {
31        self.0.pack::<BigEndian>(buffer)
32    }
33}
34
35impl<T> Unpack for LE<T> where T: Unpack {
36    fn unpack<B>(buffer: &[u8]) -> Result<Self> where B: ByteOrder {
37        Ok(Self(T::unpack::<LittleEndian>(buffer)?))
38    }
39}
40
41impl<T> Unpack for BE<T> where T: Unpack {
42    fn unpack<B>(buffer: &[u8]) -> Result<Self> where B: ByteOrder {
43        Ok(Self(T::unpack::<BigEndian>(buffer)?))
44    }
45}
46
47/// A small convenience trait similar to [`Into`] and [`TryInto`].
48pub trait UnpackInto<T> {
49    /// Decodes to a target type. May panic if the buffer is too small.
50    fn unpack_into<B>(self) -> unpack::Result<T> where B: ByteOrder;
51
52    /// Decodes to a target type, erroring if the buffer is too small.
53    fn unpack_safely_into<B>(self) -> unpack::Result<T> where B: ByteOrder;
54}
55
56impl<T> UnpackInto<T> for &[u8] where T: Unpack {
57    fn unpack_into<B>(self) -> unpack::Result<T> where B: ByteOrder {
58        T::unpack::<B>(self)
59    }
60
61    fn unpack_safely_into<B>(self) -> unpack::Result<T> where B: ByteOrder {
62        T::unpack_safely::<B>(self)
63    }
64}
65
66/// A small convenience trait that combines [`Pack`] and [`Size`].
67pub trait PackSize {
68    /// Encodes `self` to a binary representation and
69    /// returns the encoded size.
70    fn pack_size<B>(&self, buffer: &mut [u8]) -> usize where B: ByteOrder;
71}
72
73impl<T> PackSize for T where T: Pack {
74    fn pack_size<B>(&self, buffer: &mut [u8]) -> usize where B: ByteOrder {
75        self.pack::<B>(buffer);
76        T::SIZE
77    }
78}