1//! Change MessagePack behavior with configuration wrappers.
23/// Represents configuration that dicatates what the serializer does.
4///
5/// Implemented as an empty trait depending on a hidden trait in order to allow changing the
6/// methods of this trait without breaking backwards compatibility.
7pub trait SerializerConfig: sealed::SerializerConfig {}
89impl<T: sealed::SerializerConfig> SerializerConfig for T {}
1011pub(crate) mod sealed {
12use crate::config::BytesMode;
1314/// This is the inner trait - the real `SerializerConfig`.
15 ///
16 /// This hack disallows external implementations and usage of `SerializerConfig` and thus
17 /// allows us to change `SerializerConfig` methods freely without breaking backwards compatibility.
18pub trait SerializerConfig: Copy {
19/// Determines the value of `Serializer::is_human_readable` and
20 /// `Deserializer::is_human_readable`.
21fn is_human_readable(&self) -> bool;
2223/// String struct fields
24fn is_named(&self) -> bool;
25fn bytes(&self) -> BytesMode;
26 }
27}
2829#[derive(Copy, Clone, Debug)]
30pub(crate) struct RuntimeConfig {
31pub(crate) is_human_readable: bool,
32pub(crate) is_named: bool,
33pub(crate) bytes: BytesMode,
34}
3536/// When to encode `[u8]` as `bytes` rather than a sequence
37/// of integers. Serde without `serde_bytes` has trouble
38/// using `bytes`, and this is hack to force it. It may
39/// break some data types.
40#[non_exhaustive]
41#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
42pub enum BytesMode {
43/// Use bytes only when Serde requires it
44 /// (typically only when `serde_bytes` is used)
45#[default]
46Normal,
47/// Use bytes for slices, `Vec`, and a few other types that
48 /// use `Iterator` in Serde.
49 ///
50 /// This may break some implementations of `Deserialize`.
51 ///
52 /// This does not include fixed-length arrays.
53ForceIterables,
54/// Use bytes for everything that looks like a container of `u8`.
55 /// This breaks some implementations of `Deserialize`.
56ForceAll,
57}
5859impl RuntimeConfig {
60pub(crate) fn new(other: impl sealed::SerializerConfig) -> Self {
61Self {
62 is_human_readable: other.is_human_readable(),
63 is_named: other.is_named(),
64 bytes: other.bytes(),
65 }
66 }
67}
6869impl sealed::SerializerConfig for RuntimeConfig {
70#[inline]
71fn is_human_readable(&self) -> bool {
72self.is_human_readable
73 }
7475#[inline]
76fn is_named(&self) -> bool {
77self.is_named
78 }
7980#[inline]
81fn bytes(&self) -> BytesMode {
82self.bytes
83 }
84}
8586/// The default serializer/deserializer configuration.
87///
88/// This configuration:
89/// - Writes structs as a tuple, without field names
90/// - Writes enum variants as integers
91/// - Writes and reads types as binary, not human-readable
92//
93/// This is the most compact representation.
94#[derive(Copy, Clone, Debug)]
95pub struct DefaultConfig;
9697impl sealed::SerializerConfig for DefaultConfig {
98#[inline(always)]
99fn is_named(&self) -> bool {
100false
101}
102103#[inline(always)]
104fn is_human_readable(&self) -> bool {
105false
106}
107108#[inline(always)]
109fn bytes(&self) -> BytesMode {
110 BytesMode::default()
111 }
112}
113114/// Config wrapper, that overrides struct serialization by packing as a map with field names.
115///
116/// MessagePack specification does not tell how to serialize structs. This trait allows you to
117/// extend serialization to match your app's requirements.
118///
119/// Default `Serializer` implementation writes structs as a tuple, i.e. only its length is encoded,
120/// because it is the most compact representation.
121#[derive(Copy, Clone, Debug)]
122pub struct StructMapConfig<C>(C);
123124impl<C> StructMapConfig<C> {
125/// Creates a `StructMapConfig` inheriting unchanged configuration options from the given configuration.
126#[inline]
127pub fn new(inner: C) -> Self {
128 StructMapConfig(inner)
129 }
130}
131132impl<C> sealed::SerializerConfig for StructMapConfig<C>
133where
134C: sealed::SerializerConfig,
135{
136#[inline(always)]
137fn is_named(&self) -> bool {
138true
139}
140141#[inline(always)]
142fn is_human_readable(&self) -> bool {
143self.0.is_human_readable()
144 }
145146fn bytes(&self) -> BytesMode {
147self.0.bytes()
148 }
149}
150151/// Config wrapper that overrides struct serlization by packing as a tuple without field
152/// names.
153#[derive(Copy, Clone, Debug)]
154pub struct StructTupleConfig<C>(C);
155156impl<C> StructTupleConfig<C> {
157/// Creates a `StructTupleConfig` inheriting unchanged configuration options from the given configuration.
158#[inline]
159pub fn new(inner: C) -> Self {
160 StructTupleConfig(inner)
161 }
162}
163164impl<C> sealed::SerializerConfig for StructTupleConfig<C>
165where
166C: sealed::SerializerConfig,
167{
168#[inline(always)]
169fn is_named(&self) -> bool {
170false
171}
172173#[inline(always)]
174fn is_human_readable(&self) -> bool {
175self.0.is_human_readable()
176 }
177178fn bytes(&self) -> BytesMode {
179self.0.bytes()
180 }
181}
182183/// Config wrapper that overrides `Serializer::is_human_readable` and
184/// `Deserializer::is_human_readable` to return `true`.
185#[derive(Copy, Clone, Debug)]
186pub struct HumanReadableConfig<C>(C);
187188impl<C> HumanReadableConfig<C> {
189/// Creates a `HumanReadableConfig` inheriting unchanged configuration options from the given configuration.
190#[inline]
191pub fn new(inner: C) -> Self {
192Self(inner)
193 }
194}
195196impl<C> sealed::SerializerConfig for HumanReadableConfig<C>
197where
198C: sealed::SerializerConfig,
199{
200#[inline(always)]
201fn is_named(&self) -> bool {
202self.0.is_named()
203 }
204205#[inline(always)]
206fn is_human_readable(&self) -> bool {
207true
208}
209210fn bytes(&self) -> BytesMode {
211self.0.bytes()
212 }
213}
214215/// Config wrapper that overrides `Serializer::is_human_readable` and
216/// `Deserializer::is_human_readable` to return `false`.
217#[derive(Copy, Clone, Debug)]
218pub struct BinaryConfig<C>(C);
219220impl<C> BinaryConfig<C> {
221/// Creates a `BinaryConfig` inheriting unchanged configuration options from the given configuration.
222#[inline(always)]
223pub fn new(inner: C) -> Self {
224Self(inner)
225 }
226}
227228impl<C> sealed::SerializerConfig for BinaryConfig<C>
229where
230C: sealed::SerializerConfig,
231{
232#[inline(always)]
233fn is_named(&self) -> bool {
234self.0.is_named()
235 }
236237#[inline(always)]
238fn is_human_readable(&self) -> bool {
239false
240}
241242fn bytes(&self) -> BytesMode {
243self.0.bytes()
244 }
245}