/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rmp-serde-1.3.0/src/config.rs
Line | Count | Source |
1 | | //! Change MessagePack behavior with configuration wrappers. |
2 | | |
3 | | /// 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. |
7 | | pub trait SerializerConfig: sealed::SerializerConfig {} |
8 | | |
9 | | impl<T: sealed::SerializerConfig> SerializerConfig for T {} |
10 | | |
11 | | pub(crate) mod sealed { |
12 | | use crate::config::BytesMode; |
13 | | |
14 | | /// 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. |
18 | | pub trait SerializerConfig: Copy { |
19 | | /// Determines the value of `Serializer::is_human_readable` and |
20 | | /// `Deserializer::is_human_readable`. |
21 | | fn is_human_readable(&self) -> bool; |
22 | | |
23 | | /// String struct fields |
24 | | fn is_named(&self) -> bool; |
25 | | fn bytes(&self) -> BytesMode; |
26 | | } |
27 | | } |
28 | | |
29 | | #[derive(Copy, Clone, Debug)] |
30 | | pub(crate) struct RuntimeConfig { |
31 | | pub(crate) is_human_readable: bool, |
32 | | pub(crate) is_named: bool, |
33 | | pub(crate) bytes: BytesMode, |
34 | | } |
35 | | |
36 | | /// 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)] |
42 | | pub enum BytesMode { |
43 | | /// Use bytes only when Serde requires it |
44 | | /// (typically only when `serde_bytes` is used) |
45 | | #[default] |
46 | | Normal, |
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. |
53 | | ForceIterables, |
54 | | /// Use bytes for everything that looks like a container of `u8`. |
55 | | /// This breaks some implementations of `Deserialize`. |
56 | | ForceAll, |
57 | | } |
58 | | |
59 | | impl RuntimeConfig { |
60 | 0 | pub(crate) fn new(other: impl sealed::SerializerConfig) -> Self { |
61 | 0 | Self { |
62 | 0 | is_human_readable: other.is_human_readable(), |
63 | 0 | is_named: other.is_named(), |
64 | 0 | bytes: other.bytes(), |
65 | 0 | } |
66 | 0 | } |
67 | | } |
68 | | |
69 | | impl sealed::SerializerConfig for RuntimeConfig { |
70 | | #[inline] |
71 | 0 | fn is_human_readable(&self) -> bool { |
72 | 0 | self.is_human_readable |
73 | 0 | } |
74 | | |
75 | | #[inline] |
76 | 0 | fn is_named(&self) -> bool { |
77 | 0 | self.is_named |
78 | 0 | } |
79 | | |
80 | | #[inline] |
81 | 0 | fn bytes(&self) -> BytesMode { |
82 | 0 | self.bytes |
83 | 0 | } |
84 | | } |
85 | | |
86 | | /// 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)] |
95 | | pub struct DefaultConfig; |
96 | | |
97 | | impl sealed::SerializerConfig for DefaultConfig { |
98 | | #[inline(always)] |
99 | 0 | fn is_named(&self) -> bool { |
100 | 0 | false |
101 | 0 | } |
102 | | |
103 | | #[inline(always)] |
104 | 0 | fn is_human_readable(&self) -> bool { |
105 | 0 | false |
106 | 0 | } |
107 | | |
108 | | #[inline(always)] |
109 | 0 | fn bytes(&self) -> BytesMode { |
110 | 0 | BytesMode::default() |
111 | 0 | } |
112 | | } |
113 | | |
114 | | /// 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)] |
122 | | pub struct StructMapConfig<C>(C); |
123 | | |
124 | | impl<C> StructMapConfig<C> { |
125 | | /// Creates a `StructMapConfig` inheriting unchanged configuration options from the given configuration. |
126 | | #[inline] |
127 | 0 | pub fn new(inner: C) -> Self { |
128 | 0 | StructMapConfig(inner) |
129 | 0 | } |
130 | | } |
131 | | |
132 | | impl<C> sealed::SerializerConfig for StructMapConfig<C> |
133 | | where |
134 | | C: sealed::SerializerConfig, |
135 | | { |
136 | | #[inline(always)] |
137 | 0 | fn is_named(&self) -> bool { |
138 | 0 | true |
139 | 0 | } |
140 | | |
141 | | #[inline(always)] |
142 | 0 | fn is_human_readable(&self) -> bool { |
143 | 0 | self.0.is_human_readable() |
144 | 0 | } |
145 | | |
146 | 0 | fn bytes(&self) -> BytesMode { |
147 | 0 | self.0.bytes() |
148 | 0 | } |
149 | | } |
150 | | |
151 | | /// Config wrapper that overrides struct serlization by packing as a tuple without field |
152 | | /// names. |
153 | | #[derive(Copy, Clone, Debug)] |
154 | | pub struct StructTupleConfig<C>(C); |
155 | | |
156 | | impl<C> StructTupleConfig<C> { |
157 | | /// Creates a `StructTupleConfig` inheriting unchanged configuration options from the given configuration. |
158 | | #[inline] |
159 | 0 | pub fn new(inner: C) -> Self { |
160 | 0 | StructTupleConfig(inner) |
161 | 0 | } |
162 | | } |
163 | | |
164 | | impl<C> sealed::SerializerConfig for StructTupleConfig<C> |
165 | | where |
166 | | C: sealed::SerializerConfig, |
167 | | { |
168 | | #[inline(always)] |
169 | 0 | fn is_named(&self) -> bool { |
170 | 0 | false |
171 | 0 | } |
172 | | |
173 | | #[inline(always)] |
174 | 0 | fn is_human_readable(&self) -> bool { |
175 | 0 | self.0.is_human_readable() |
176 | 0 | } |
177 | | |
178 | 0 | fn bytes(&self) -> BytesMode { |
179 | 0 | self.0.bytes() |
180 | 0 | } |
181 | | } |
182 | | |
183 | | /// Config wrapper that overrides `Serializer::is_human_readable` and |
184 | | /// `Deserializer::is_human_readable` to return `true`. |
185 | | #[derive(Copy, Clone, Debug)] |
186 | | pub struct HumanReadableConfig<C>(C); |
187 | | |
188 | | impl<C> HumanReadableConfig<C> { |
189 | | /// Creates a `HumanReadableConfig` inheriting unchanged configuration options from the given configuration. |
190 | | #[inline] |
191 | 0 | pub fn new(inner: C) -> Self { |
192 | 0 | Self(inner) |
193 | 0 | } |
194 | | } |
195 | | |
196 | | impl<C> sealed::SerializerConfig for HumanReadableConfig<C> |
197 | | where |
198 | | C: sealed::SerializerConfig, |
199 | | { |
200 | | #[inline(always)] |
201 | 0 | fn is_named(&self) -> bool { |
202 | 0 | self.0.is_named() |
203 | 0 | } |
204 | | |
205 | | #[inline(always)] |
206 | 0 | fn is_human_readable(&self) -> bool { |
207 | 0 | true |
208 | 0 | } |
209 | | |
210 | 0 | fn bytes(&self) -> BytesMode { |
211 | 0 | self.0.bytes() |
212 | 0 | } |
213 | | } |
214 | | |
215 | | /// Config wrapper that overrides `Serializer::is_human_readable` and |
216 | | /// `Deserializer::is_human_readable` to return `false`. |
217 | | #[derive(Copy, Clone, Debug)] |
218 | | pub struct BinaryConfig<C>(C); |
219 | | |
220 | | impl<C> BinaryConfig<C> { |
221 | | /// Creates a `BinaryConfig` inheriting unchanged configuration options from the given configuration. |
222 | | #[inline(always)] |
223 | 0 | pub fn new(inner: C) -> Self { |
224 | 0 | Self(inner) |
225 | 0 | } |
226 | | } |
227 | | |
228 | | impl<C> sealed::SerializerConfig for BinaryConfig<C> |
229 | | where |
230 | | C: sealed::SerializerConfig, |
231 | | { |
232 | | #[inline(always)] |
233 | 0 | fn is_named(&self) -> bool { |
234 | 0 | self.0.is_named() |
235 | 0 | } |
236 | | |
237 | | #[inline(always)] |
238 | 0 | fn is_human_readable(&self) -> bool { |
239 | 0 | false |
240 | 0 | } |
241 | | |
242 | 0 | fn bytes(&self) -> BytesMode { |
243 | 0 | self.0.bytes() |
244 | 0 | } |
245 | | } |