Skip to main content

msgpacker/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(missing_docs)]
3#![doc = include_str!("../README.md")]
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8#[cfg(feature = "alloc")]
9mod extension;
10
11mod error;
12mod format;
13mod helpers;
14pub(crate) mod pack;
15pub(crate) mod unpack;
16
17#[cfg(feature = "serde")]
18pub mod serde;
19
20pub use error::Error;
21use format::Format;
22pub use pack::{pack_array, pack_map};
23pub use unpack::{unpack_array, unpack_array_iter, unpack_map, unpack_map_iter};
24
25#[cfg(feature = "alloc")]
26pub use extension::Extension;
27
28#[cfg(feature = "alloc")]
29use alloc::vec::Vec;
30
31#[cfg(feature = "derive")]
32pub use msgpacker_derive::MsgPacker;
33
34/// Packs the provided packable value into a vector.
35#[cfg(feature = "alloc")]
36pub fn pack_to_vec<T>(value: &T) -> Vec<u8>
37where
38    T: Packable,
39{
40    value.pack_to_vec()
41}
42
43/// A packable type.
44pub trait Packable {
45    /// Pack a value into the extendable buffer, returning the amount of written bytes.
46    fn pack<T>(&self, buf: &mut T) -> usize
47    where
48        T: Extend<u8>;
49
50    /// Packs the value into a vector of bytes.
51    #[cfg(feature = "alloc")]
52    fn pack_to_vec(&self) -> Vec<u8> {
53        let mut bytes = Vec::new();
54
55        self.pack(&mut bytes);
56
57        bytes
58    }
59}
60
61impl<X> Packable for &X
62where
63    X: Packable,
64{
65    fn pack<T>(&self, buf: &mut T) -> usize
66    where
67        T: Extend<u8>,
68    {
69        X::pack(self, buf)
70    }
71}
72
73impl<X> Packable for &mut X
74where
75    X: Packable,
76{
77    fn pack<T>(&self, buf: &mut T) -> usize
78    where
79        T: Extend<u8>,
80    {
81        X::pack(self, buf)
82    }
83}
84
85/// An unpackable type.
86///
87/// It provides two methods of deserialization: via slices of bytes and iterators.
88///
89/// Slices of bytes are more performant than iterators, but they require the bytes to be eagerly
90/// loaded. If a lazy load deserialization is needed, then use `unpack_iter`.
91pub trait Unpackable: Sized {
92    /// Concrete error implementation for the serialization.
93    ///
94    /// Must interop with [Error].
95    type Error: From<Error>;
96
97    /// Unpacks a value from the buffer, returning the deserialized value and the amount of read
98    /// bytes.
99    fn unpack(buf: &[u8]) -> Result<(usize, Self), Self::Error>;
100
101    /// Unpacks a value from an iterator of bytes, returning the deserialized value and the amount
102    /// of read bytes.
103    ///
104    /// This should be used only if lazy load is required. [Unpackable::unpack] outperforms
105    /// iterators with a large margin.
106    fn unpack_iter<I>(bytes: I) -> Result<(usize, Self), Self::Error>
107    where
108        I: IntoIterator<Item = u8>;
109}
110
111/// Required types for the library.
112pub mod prelude {
113    pub use super::{Error, Packable, Unpackable};
114
115    #[cfg(feature = "derive")]
116    pub use super::MsgPacker;
117
118    #[cfg(feature = "alloc")]
119    pub use super::Extension;
120}