1use super::internal::{Bounded, Infinite, SizeLimit, SizeType, U16, U32, U64, U8};
2use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian};
3use de::read::BincodeRead;
4use error::Result;
5use serde;
6use std::io::{Read, Write};
7use std::marker::PhantomData;
8use {DeserializerAcceptor, SerializerAcceptor};
9
10struct DefaultOptions(Infinite);
11
12pub(crate) trait Options {
13 type Limit: SizeLimit + 'static;
14 type Endian: ByteOrder + 'static;
15 type StringSize: SizeType + 'static;
16 type ArraySize: SizeType + 'static;
17
18 fn limit(&mut self) -> &mut Self::Limit;
19}
20
21pub(crate) trait OptionsExt: Options + Sized {
22 fn with_no_limit(self) -> WithOtherLimit<Self, Infinite> {
23 WithOtherLimit::new(self, Infinite)
24 }
25
26 fn with_limit(self, limit: u64) -> WithOtherLimit<Self, Bounded> {
27 WithOtherLimit::new(self, Bounded(limit))
28 }
29
30 fn with_little_endian(self) -> WithOtherEndian<Self, LittleEndian> {
31 WithOtherEndian::new(self)
32 }
33
34 fn with_big_endian(self) -> WithOtherEndian<Self, BigEndian> {
35 WithOtherEndian::new(self)
36 }
37
38 fn with_native_endian(self) -> WithOtherEndian<Self, NativeEndian> {
39 WithOtherEndian::new(self)
40 }
41
42 fn with_string_size<S>(self) -> WithOtherStringLength<Self, S>
43 where
44 S: SizeType,
45 {
46 WithOtherStringLength::new(self)
47 }
48
49 fn with_array_size<S>(self) -> WithOtherArrayLength<Self, S>
50 where
51 S: SizeType,
52 {
53 WithOtherArrayLength::new(self)
54 }
55}
56
57impl<'a, O: Options> Options for &'a mut O {
58 type Limit = O::Limit;
59 type Endian = O::Endian;
60 type StringSize = O::StringSize;
61 type ArraySize = O::ArraySize;
62
63 #[inline(always)]
64 fn limit(&mut self) -> &mut Self::Limit {
65 (*self).limit()
66 }
67}
68
69impl<T: Options> OptionsExt for T {}
70
71impl DefaultOptions {
72 fn new() -> DefaultOptions {
73 DefaultOptions(Infinite)
74 }
75}
76
77impl Options for DefaultOptions {
78 type Limit = Infinite;
79 type Endian = LittleEndian;
80 type StringSize = U64;
81 type ArraySize = U64;
82
83 #[inline(always)]
84 fn limit(&mut self) -> &mut Infinite {
85 &mut self.0
86 }
87}
88
89#[derive(Clone, Copy, Debug)]
90enum LimitOption {
91 Unlimited,
92 Limited(u64),
93}
94
95#[derive(Clone, Copy, Debug)]
96enum EndianOption {
97 Big,
98 Little,
99 Native,
100}
101
102#[derive(Clone, Copy, Debug)]
104pub enum LengthOption {
105 U64,
107 U32,
109 U16,
111 U8,
113}
114
115#[derive(Clone, Debug)]
137pub struct Config {
138 limit: LimitOption,
139 endian: EndianOption,
140 string_size: LengthOption,
141 array_size: LengthOption,
142}
143
144pub(crate) struct WithOtherLimit<O: Options, L: SizeLimit> {
145 _options: O,
146 pub(crate) new_limit: L,
147}
148
149pub(crate) struct WithOtherEndian<O: Options, E: ByteOrder> {
150 options: O,
151 _endian: PhantomData<E>,
152}
153
154pub(crate) struct WithOtherStringLength<O: Options, L: SizeType> {
155 options: O,
156 _new_string_length: PhantomData<L>,
157}
158
159pub(crate) struct WithOtherArrayLength<O: Options, L: SizeType> {
160 options: O,
161 _new_array_length: PhantomData<L>,
162}
163
164impl<O: Options, L: SizeLimit> WithOtherLimit<O, L> {
165 #[inline(always)]
166 pub(crate) fn new(options: O, limit: L) -> WithOtherLimit<O, L> {
167 WithOtherLimit {
168 _options: options,
169 new_limit: limit,
170 }
171 }
172}
173
174impl<O: Options, E: ByteOrder> WithOtherEndian<O, E> {
175 #[inline(always)]
176 pub(crate) fn new(options: O) -> WithOtherEndian<O, E> {
177 WithOtherEndian {
178 options,
179 _endian: PhantomData,
180 }
181 }
182}
183
184impl<O: Options, L: SizeType> WithOtherStringLength<O, L> {
185 #[inline(always)]
186 pub(crate) fn new(options: O) -> WithOtherStringLength<O, L> {
187 WithOtherStringLength {
188 options,
189 _new_string_length: PhantomData,
190 }
191 }
192}
193
194impl<O: Options, L: SizeType> WithOtherArrayLength<O, L> {
195 #[inline(always)]
196 pub(crate) fn new(options: O) -> WithOtherArrayLength<O, L> {
197 WithOtherArrayLength {
198 options,
199 _new_array_length: PhantomData,
200 }
201 }
202}
203
204impl<O: Options, E: ByteOrder + 'static> Options for WithOtherEndian<O, E> {
205 type Limit = O::Limit;
206 type Endian = E;
207 type StringSize = O::StringSize;
208 type ArraySize = O::ArraySize;
209
210 #[inline(always)]
211 fn limit(&mut self) -> &mut O::Limit {
212 self.options.limit()
213 }
214}
215
216impl<O: Options, L: SizeLimit + 'static> Options for WithOtherLimit<O, L> {
217 type Limit = L;
218 type Endian = O::Endian;
219 type StringSize = O::StringSize;
220 type ArraySize = O::ArraySize;
221
222 fn limit(&mut self) -> &mut L {
223 &mut self.new_limit
224 }
225}
226
227impl<O: Options, L: SizeType + 'static> Options for WithOtherStringLength<O, L> {
228 type Limit = O::Limit;
229 type Endian = O::Endian;
230 type StringSize = L;
231 type ArraySize = O::ArraySize;
232
233 fn limit(&mut self) -> &mut O::Limit {
234 self.options.limit()
235 }
236}
237
238impl<O: Options, L: SizeType + 'static> Options for WithOtherArrayLength<O, L> {
239 type Limit = O::Limit;
240 type Endian = O::Endian;
241 type StringSize = O::StringSize;
242 type ArraySize = L;
243
244 fn limit(&mut self) -> &mut O::Limit {
245 self.options.limit()
246 }
247}
248
249macro_rules! config_map_limit {
250 ($self:expr, $opts:ident => $call:expr) => {
251 match $self.limit {
252 LimitOption::Unlimited => {
253 let $opts = $opts.with_no_limit();
254 $call
255 }
256 LimitOption::Limited(l) => {
257 let $opts = $opts.with_limit(l);
258 $call
259 }
260 }
261 };
262}
263
264macro_rules! config_map_endian {
265 ($self:expr, $opts:ident => $call:expr) => {
266 match $self.endian {
267 EndianOption::Little => {
268 let $opts = $opts.with_little_endian();
269 $call
270 }
271 EndianOption::Big => {
272 let $opts = $opts.with_big_endian();
273 $call
274 }
275 EndianOption::Native => {
276 let $opts = $opts.with_native_endian();
277 $call
278 }
279 }
280 };
281}
282
283macro_rules! config_map_string_length {
284 ($self:expr, $opts:ident => $call:expr) => {
285 match $self.string_size {
286 LengthOption::U64 => {
287 let $opts = $opts.with_string_size::<U64>();
288 $call
289 }
290 LengthOption::U32 => {
291 let $opts = $opts.with_string_size::<U32>();
292 $call
293 }
294 LengthOption::U16 => {
295 let $opts = $opts.with_string_size::<U16>();
296 $call
297 }
298 LengthOption::U8 => {
299 let $opts = $opts.with_string_size::<U8>();
300 $call
301 }
302 }
303 };
304}
305
306macro_rules! config_map_array_length {
307 ($self:expr, $opts:ident => $call:expr) => {
308 match $self.array_size {
309 LengthOption::U64 => {
310 let $opts = $opts.with_array_size::<U64>();
311 $call
312 }
313 LengthOption::U32 => {
314 let $opts = $opts.with_array_size::<U32>();
315 $call
316 }
317 LengthOption::U16 => {
318 let $opts = $opts.with_array_size::<U16>();
319 $call
320 }
321 LengthOption::U8 => {
322 let $opts = $opts.with_array_size::<U8>();
323 $call
324 }
325 }
326 };
327}
328
329macro_rules! config_map {
330 ($self:expr, $opts:ident => $call:expr) => {{
331 let $opts = DefaultOptions::new();
332 config_map_limit!($self, $opts =>
333 config_map_endian!($self, $opts =>
334 config_map_string_length!($self, $opts =>
335 config_map_array_length!($self, $opts => $call))))
336 }}
337}
338
339#[allow(clippy::cognitive_complexity)] impl Config {
341 #[inline(always)]
342 pub(crate) fn new() -> Config {
343 Config {
344 limit: LimitOption::Unlimited,
345 endian: EndianOption::Little,
346 string_size: LengthOption::U64,
347 array_size: LengthOption::U64,
348 }
349 }
350
351 #[inline(always)]
354 pub fn no_limit(&mut self) -> &mut Self {
355 self.limit = LimitOption::Unlimited;
356 self
357 }
358
359 #[inline(always)]
361 pub fn limit(&mut self, limit: u64) -> &mut Self {
362 self.limit = LimitOption::Limited(limit);
363 self
364 }
365
366 #[inline(always)]
369 pub fn little_endian(&mut self) -> &mut Self {
370 self.endian = EndianOption::Little;
371 self
372 }
373
374 #[inline(always)]
376 pub fn big_endian(&mut self) -> &mut Self {
377 self.endian = EndianOption::Big;
378 self
379 }
380
381 #[inline(always)]
383 pub fn native_endian(&mut self) -> &mut Self {
384 self.endian = EndianOption::Native;
385 self
386 }
387
388 #[inline(always)]
390 pub fn string_length(&mut self, size: LengthOption) -> &mut Self {
391 self.string_size = size;
392 self
393 }
394
395 #[inline(always)]
397 pub fn array_length(&mut self, size: LengthOption) -> &mut Self {
398 self.array_size = size;
399 self
400 }
401
402 #[inline(always)]
404 pub fn serialize<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<Vec<u8>> {
405 config_map!(self, opts => ::internal::serialize(t, opts))
406 }
407
408 #[inline(always)]
410 pub fn serialized_size<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<u64> {
411 config_map!(self, opts => ::internal::serialized_size(t, opts))
412 }
413
414 #[inline(always)]
419 pub fn serialize_into<W: Write, T: ?Sized + serde::Serialize>(
420 &self,
421 w: W,
422 t: &T,
423 ) -> Result<()> {
424 config_map!(self, opts => ::internal::serialize_into(w, t, opts))
425 }
426
427 #[inline(always)]
429 pub fn deserialize<'a, T: serde::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T> {
430 config_map!(self, opts => ::internal::deserialize(bytes, opts))
431 }
432
433 #[doc(hidden)]
435 #[inline(always)]
436 pub fn deserialize_in_place<'a, R, T>(&self, reader: R, place: &mut T) -> Result<()>
437 where
438 R: BincodeRead<'a>,
439 T: serde::de::Deserialize<'a>,
440 {
441 config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place))
442 }
443
444 #[inline(always)]
446 pub fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>(
447 &self,
448 seed: T,
449 bytes: &'a [u8],
450 ) -> Result<T::Value> {
451 config_map!(self, opts => ::internal::deserialize_seed(seed, bytes, opts))
452 }
453
454 #[inline(always)]
458 pub fn deserialize_from<R: Read, T: serde::de::DeserializeOwned>(
459 &self,
460 reader: R,
461 ) -> Result<T> {
462 config_map!(self, opts => ::internal::deserialize_from(reader, opts))
463 }
464
465 #[inline(always)]
469 pub fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>(
470 &self,
471 seed: T,
472 reader: R,
473 ) -> Result<T::Value> {
474 config_map!(self, opts => ::internal::deserialize_from_seed(seed, reader, opts))
475 }
476
477 #[inline(always)]
483 pub fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>(
484 &self,
485 reader: R,
486 ) -> Result<T> {
487 config_map!(self, opts => ::internal::deserialize_from_custom(reader, opts))
488 }
489
490 #[inline(always)]
496 pub fn deserialize_from_custom_seed<
497 'a,
498 R: BincodeRead<'a>,
499 T: serde::de::DeserializeSeed<'a>,
500 >(
501 &self,
502 seed: T,
503 reader: R,
504 ) -> Result<T::Value> {
505 config_map!(self, opts => ::internal::deserialize_from_custom_seed(seed, reader, opts))
506 }
507
508 #[doc(hidden)]
511 pub fn with_deserializer<'a, A, R>(&self, reader: R, acceptor: A) -> A::Output
512 where
513 A: DeserializerAcceptor<'a>,
514 R: BincodeRead<'a>,
515 {
516 config_map!(self, opts => {
517 let mut deserializer = ::de::Deserializer::new(reader, opts);
518 acceptor.accept(&mut deserializer)
519 })
520 }
521
522 #[doc(hidden)]
525 pub fn with_serializer<A, W>(&self, writer: W, acceptor: A) -> A::Output
526 where
527 A: SerializerAcceptor,
528 W: Write,
529 {
530 config_map!(self, opts => {
531 let mut serializer = ::ser::Serializer::new(writer, opts);
532 acceptor.accept(&mut serializer)
533 })
534 }
535}