1use super::internal::{Bounded, Infinite, SizeLimit};
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
10use self::EndianOption::*;
11use self::LimitOption::*;
12
13struct DefaultOptions(Infinite);
14
15pub(crate) trait Options {
16 type Limit: SizeLimit + 'static;
17 type Endian: ByteOrder + 'static;
18
19 fn limit(&mut self) -> &mut Self::Limit;
20}
21
22pub(crate) trait OptionsExt: Options + Sized {
23 fn with_no_limit(self) -> WithOtherLimit<Self, Infinite> {
24 WithOtherLimit::new(self, Infinite)
25 }
26
27 fn with_limit(self, limit: u64) -> WithOtherLimit<Self, Bounded> {
28 WithOtherLimit::new(self, Bounded(limit))
29 }
30
31 fn with_little_endian(self) -> WithOtherEndian<Self, LittleEndian> {
32 WithOtherEndian::new(self)
33 }
34
35 fn with_big_endian(self) -> WithOtherEndian<Self, BigEndian> {
36 WithOtherEndian::new(self)
37 }
38
39 fn with_native_endian(self) -> WithOtherEndian<Self, NativeEndian> {
40 WithOtherEndian::new(self)
41 }
42}
43
44impl<'a, O: Options> Options for &'a mut O {
45 type Limit = O::Limit;
46 type Endian = O::Endian;
47
48 #[inline(always)]
49 fn limit(&mut self) -> &mut Self::Limit {
50 (*self).limit()
51 }
52}
53
54impl<T: Options> OptionsExt for T {}
55
56impl DefaultOptions {
57 fn new() -> DefaultOptions {
58 DefaultOptions(Infinite)
59 }
60}
61
62impl Options for DefaultOptions {
63 type Limit = Infinite;
64 type Endian = LittleEndian;
65
66 #[inline(always)]
67 fn limit(&mut self) -> &mut Infinite {
68 &mut self.0
69 }
70}
71
72#[derive(Clone, Copy)]
73enum LimitOption {
74 Unlimited,
75 Limited(u64),
76}
77
78#[derive(Clone, Copy)]
79enum EndianOption {
80 Big,
81 Little,
82 Native,
83}
84
85pub struct Config {
99 limit: LimitOption,
100 endian: EndianOption,
101}
102
103pub(crate) struct WithOtherLimit<O: Options, L: SizeLimit> {
104 _options: O,
105 pub(crate) new_limit: L,
106}
107
108pub(crate) struct WithOtherEndian<O: Options, E: ByteOrder> {
109 options: O,
110 _endian: PhantomData<E>,
111}
112
113impl<O: Options, L: SizeLimit> WithOtherLimit<O, L> {
114 #[inline(always)]
115 pub(crate) fn new(options: O, limit: L) -> WithOtherLimit<O, L> {
116 WithOtherLimit {
117 _options: options,
118 new_limit: limit,
119 }
120 }
121}
122
123impl<O: Options, E: ByteOrder> WithOtherEndian<O, E> {
124 #[inline(always)]
125 pub(crate) fn new(options: O) -> WithOtherEndian<O, E> {
126 WithOtherEndian {
127 options: options,
128 _endian: PhantomData,
129 }
130 }
131}
132
133impl<O: Options, E: ByteOrder + 'static> Options for WithOtherEndian<O, E> {
134 type Limit = O::Limit;
135 type Endian = E;
136
137 #[inline(always)]
138 fn limit(&mut self) -> &mut O::Limit {
139 self.options.limit()
140 }
141}
142
143impl<O: Options, L: SizeLimit + 'static> Options for WithOtherLimit<O, L> {
144 type Limit = L;
145 type Endian = O::Endian;
146
147 fn limit(&mut self) -> &mut L {
148 &mut self.new_limit
149 }
150}
151
152macro_rules! config_map {
153 ($self:expr, $opts:ident => $call:expr) => {
154 match ($self.limit, $self.endian) {
155 (Unlimited, Little) => {
156 let $opts = DefaultOptions::new().with_no_limit().with_little_endian();
157 $call
158 }
159 (Unlimited, Big) => {
160 let $opts = DefaultOptions::new().with_no_limit().with_big_endian();
161 $call
162 }
163 (Unlimited, Native) => {
164 let $opts = DefaultOptions::new().with_no_limit().with_native_endian();
165 $call
166 }
167
168 (Limited(l), Little) => {
169 let $opts = DefaultOptions::new().with_limit(l).with_little_endian();
170 $call
171 }
172 (Limited(l), Big) => {
173 let $opts = DefaultOptions::new().with_limit(l).with_big_endian();
174 $call
175 }
176 (Limited(l), Native) => {
177 let $opts = DefaultOptions::new().with_limit(l).with_native_endian();
178 $call
179 }
180 }
181 };
182}
183
184impl Config {
185 #[inline(always)]
186 pub(crate) fn new() -> Config {
187 Config {
188 limit: LimitOption::Unlimited,
189 endian: EndianOption::Little,
190 }
191 }
192
193 #[inline(always)]
196 pub fn no_limit(&mut self) -> &mut Self {
197 self.limit = LimitOption::Unlimited;
198 self
199 }
200
201 #[inline(always)]
203 pub fn limit(&mut self, limit: u64) -> &mut Self {
204 self.limit = LimitOption::Limited(limit);
205 self
206 }
207
208 #[inline(always)]
211 pub fn little_endian(&mut self) -> &mut Self {
212 self.endian = EndianOption::Little;
213 self
214 }
215
216 #[inline(always)]
218 pub fn big_endian(&mut self) -> &mut Self {
219 self.endian = EndianOption::Big;
220 self
221 }
222
223 #[inline(always)]
225 pub fn native_endian(&mut self) -> &mut Self {
226 self.endian = EndianOption::Native;
227 self
228 }
229
230 #[inline(always)]
232 pub fn serialize<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<Vec<u8>> {
233 config_map!(self, opts => ::internal::serialize(t, opts))
234 }
235
236 #[inline(always)]
238 pub fn serialized_size<T: ?Sized + serde::Serialize>(&self, t: &T) -> Result<u64> {
239 config_map!(self, opts => ::internal::serialized_size(t, opts))
240 }
241
242 #[inline(always)]
247 pub fn serialize_into<W: Write, T: ?Sized + serde::Serialize>(
248 &self,
249 w: W,
250 t: &T,
251 ) -> Result<()> {
252 config_map!(self, opts => ::internal::serialize_into(w, t, opts))
253 }
254
255 #[inline(always)]
257 pub fn deserialize<'a, T: serde::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T> {
258 config_map!(self, opts => ::internal::deserialize(bytes, opts))
259 }
260
261 #[doc(hidden)]
263 #[inline(always)]
264 pub fn deserialize_in_place<'a, R, T>(&self, reader: R, place: &mut T) -> Result<()>
265 where
266 R: BincodeRead<'a>,
267 T: serde::de::Deserialize<'a>,
268 {
269 config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place))
270 }
271
272 #[inline(always)]
274 pub fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>(
275 &self,
276 seed: T,
277 bytes: &'a [u8],
278 ) -> Result<T::Value> {
279 config_map!(self, opts => ::internal::deserialize_seed(seed, bytes, opts))
280 }
281
282 #[inline(always)]
286 pub fn deserialize_from<R: Read, T: serde::de::DeserializeOwned>(
287 &self,
288 reader: R,
289 ) -> Result<T> {
290 config_map!(self, opts => ::internal::deserialize_from(reader, opts))
291 }
292
293 #[inline(always)]
299 pub fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>(
300 &self,
301 reader: R,
302 ) -> Result<T> {
303 config_map!(self, opts => ::internal::deserialize_from_custom(reader, opts))
304 }
305
306 #[doc(hidden)]
309 pub fn with_deserializer<'a, A, R>(&self, reader: R, acceptor: A) -> A::Output
310 where
311 A: DeserializerAcceptor<'a>,
312 R: BincodeRead<'a>,
313 {
314 config_map!(self, opts => {
315 let mut deserializer = ::de::Deserializer::new(reader, opts);
316 acceptor.accept(&mut deserializer)
317 })
318 }
319
320 #[doc(hidden)]
323 pub fn with_serializer<A, W>(&self, writer: W, acceptor: A) -> A::Output
324 where
325 A: SerializerAcceptor,
326 W: Write,
327 {
328 config_map!(self, opts => {
329 let mut serializer = ::ser::Serializer::new(writer, opts);
330 acceptor.accept(&mut serializer)
331 })
332 }
333}