bytevec/impls/
collections.rs

1use traits::{ByteEncodable, ByteDecodable};
2use errors::{ByteVecError, BVExpectedSize};
3use {BVEncodeResult, BVDecodeResult, BVSize};
4use std::collections::{HashMap, HashSet};
5use std::hash::Hash;
6
7macro_rules! validate_collection {
8    ($byte_vec:ident, $index:ident, $len:ident, $size_vec:ident, $ret:expr) => {{
9        if $byte_vec.len() >= Size::get_size_of().as_usize() {
10            $len = try!(Size::decode::<Size>(
11                &$byte_vec[..Size::get_size_of().as_usize()])).as_usize();
12            $index = Size::get_size_of().as_usize();
13            let sizes_len = $len * Size::get_size_of().as_usize();
14            if $byte_vec[Size::get_size_of().as_usize()..].len() >= sizes_len {
15                $size_vec = Vec::new();
16                for _ in 0..$len {
17                    $size_vec.push(try!(Size::decode::<Size>(
18                        &$byte_vec[$index..$index + Size::get_size_of().as_usize()])));
19                    $index += Size::get_size_of().as_usize();
20                }
21                let body_size = $size_vec.iter().fold(0, |acc, ref size| acc + size.as_usize());
22                if body_size == $byte_vec[Size::get_size_of().as_usize() + sizes_len..].len() {
23                    $ret
24                } else {
25                    Err(ByteVecError::BadSizeDecodeError {
26                        expected: BVExpectedSize::EqualTo(
27                            Size::get_size_of().as_usize() + sizes_len + body_size),
28                        actual: $byte_vec.len()
29                    })
30                }
31            }
32            else {
33                Err(ByteVecError::BadSizeDecodeError {
34                    expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize() + sizes_len),
35                    actual: $byte_vec.len()
36                })
37            }
38        } else {
39            Err(ByteVecError::BadSizeDecodeError {
40                expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize()),
41                actual: $byte_vec.len()
42            })
43        }
44    }};
45}
46
47impl ByteEncodable for str {
48    fn get_size<Size>(&self) -> Option<Size>
49        where Size: BVSize + ByteEncodable
50    {
51        if self.len() <= Size::max_value().as_usize() {
52            Some(Size::from_usize(self.len()))
53        } else {
54            None
55        }
56    }
57
58    fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
59        where Size: BVSize + ByteEncodable
60    {
61        if self.get_size::<Size>().is_some() {
62            let mut bytes = Vec::new();
63            bytes.extend_from_slice(&self.as_bytes().to_vec());
64            Ok(bytes)
65        } else {
66            Err(ByteVecError::OverflowError)
67        }
68    }
69}
70
71impl<'a> ByteEncodable for &'a str {
72    fn get_size<Size>(&self) -> Option<Size>
73        where Size: BVSize + ByteEncodable
74    {
75        (**self).get_size::<Size>()
76    }
77
78    fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
79        where Size: BVSize + ByteEncodable
80    {
81        (**self).encode::<Size>()
82    }
83}
84
85impl ByteEncodable for String {
86    fn get_size<Size>(&self) -> Option<Size>
87        where Size: BVSize + ByteEncodable
88    {
89        (**self).get_size::<Size>()
90    }
91
92    fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
93        where Size: BVSize + ByteEncodable
94    {
95        (**self).encode::<Size>()
96    }
97}
98
99impl ByteDecodable for String {
100    fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<String>
101        where Size: BVSize + ByteDecodable
102    {
103        Ok(try!(::std::str::from_utf8(bytes)).to_string())
104    }
105}
106
107macro_rules! collection_encode_impl {
108    () => {
109        fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
110            self.iter()
111                .fold(Some(Size::from_usize(0)), |acc, elem| {
112                    acc.and_then(|acc: Size| {
113                        (&elem)
114                            .get_size::<Size>()
115                            .and_then(|size| {
116                                acc.checked_add(size).and_then(|acc_size|
117                                    acc_size.checked_add(Size::get_size_of())
118                                )
119                            })
120                    })
121                })
122                .and_then(|total: Size| total.checked_add(Size::get_size_of()))
123        }
124
125        fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
126            if self.get_size::<Size>().is_some() {
127                let mut bytes = Vec::new();
128                bytes.extend_from_slice(&try!((Size::from_usize(self.len())).encode::<Size>()));
129                for elem in self {
130                    bytes.extend_from_slice(&try!(
131                        (&elem).get_size::<Size>().unwrap().encode::<Size>()));
132                }
133                for elem in self {
134                    bytes.extend_from_slice(&try!((&elem).encode::<Size>()));
135                }
136                Ok(bytes)
137            } else {
138                Err(ByteVecError::OverflowError)
139            }
140        }
141    }
142}
143
144impl<T> ByteEncodable for Vec<T>
145    where T: ByteEncodable
146{
147    collection_encode_impl!();
148}
149
150impl<T> ByteDecodable for Vec<T>
151    where T: ByteDecodable
152{
153    fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<Vec<T>>
154        where Size: BVSize + ByteDecodable
155    {
156        let len;
157        let mut index;
158        let mut sizes;
159        validate_collection!(bytes, index, len, sizes, {
160            let mut vec = Vec::with_capacity(len);
161            for size in sizes.into_iter() {
162                vec.push(try!(T::decode::<Size>(&bytes[index..index + size.as_usize()])));
163                index += size.as_usize();
164            }
165            Ok(vec)
166        })
167    }
168}
169
170impl<T> ByteEncodable for [T]
171    where T: ByteEncodable
172{
173    collection_encode_impl!();
174}
175
176impl<T> ByteEncodable for HashSet<T>
177    where T: ByteEncodable + Eq + Hash
178{
179    collection_encode_impl!();
180}
181
182impl<T> ByteDecodable for HashSet<T>
183    where T: ByteDecodable + Eq + Hash
184{
185    fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<HashSet<T>>
186        where Size: BVSize + ByteDecodable
187    {
188        let len;
189        let mut index;
190        let mut sizes;
191        validate_collection!(bytes, index, len, sizes, {
192            let mut set = HashSet::with_capacity(len);
193            for size in sizes.into_iter() {
194                set.insert(try!(T::decode::<Size>(&bytes[index..index + size.as_usize()])));
195                index += size.as_usize();
196            }
197            Ok(set)
198        })
199    }
200}
201
202impl<K, V> ByteEncodable for HashMap<K, V>
203    where K: ByteEncodable + Hash + Eq,
204          V: ByteEncodable
205{
206    collection_encode_impl!();
207}
208
209impl<K, V> ByteDecodable for HashMap<K, V>
210    where K: ByteDecodable + Hash + Eq,
211          V: ByteDecodable
212{
213    fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<HashMap<K, V>>
214        where Size: BVSize + ByteDecodable
215    {
216        let len;
217        let mut index;
218        let mut sizes;
219        validate_collection!(bytes, index, len, sizes, {
220            let mut map = HashMap::with_capacity(len);
221            for size in sizes.into_iter() {
222                let (key, value) = try!(<(K, V)>::decode::<Size>(&bytes[index..index +
223                                                                               size.as_usize()]));
224                map.insert(key, value);
225                index += size.as_usize();
226            }
227            Ok(map)
228        })
229    }
230}
231
232macro_rules! tuple_impls {
233    ($t:ident: $elem:ident) => {
234        impl<$t,> ByteEncodable for ($t,)
235            where $t: ByteEncodable
236        {
237            fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
238                (&(&self.0)).get_size::<Size>()
239            }
240
241            fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
242                (&(&self.0)).encode::<Size>()
243            }
244        }
245
246        impl<'a, $t,> ByteEncodable for &'a (&'a $t,)
247            where $t: ByteEncodable
248        {
249            fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
250                self.0.get_size::<Size>().and_then(|elem_size|
251                    elem_size.checked_add(Size::get_size_of()))
252            }
253
254            fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
255                if self.get_size::<Size>().is_some() {
256                    let mut bytes = Vec::new();
257                    bytes.extend_from_slice(&try!(
258                        self.0.get_size::<Size>().unwrap().encode::<Size>()));
259                    bytes.extend_from_slice(&try!(self.0.encode::<Size>()));
260                    Ok(bytes)
261                } else {
262                    Err(ByteVecError::OverflowError)
263                }
264            }
265        }
266
267        impl<$t,> ByteDecodable for ($t,)
268            where $t: ByteDecodable
269        {
270            fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<($t,)>
271                where Size: BVSize + ByteDecodable
272            {
273                let size;
274
275                if bytes.len() >= Size::get_size_of().as_usize() {
276                    size = try!(Size::decode::<Size>(&bytes[..Size::get_size_of().as_usize()]));
277                }
278                else {
279                    return Err(ByteVecError::BadSizeDecodeError {
280                        expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize()),
281                        actual: bytes.len()
282                    });
283                }
284                if size.as_usize() == bytes[Size::get_size_of().as_usize()..].len() {
285                    Ok((try!($t::decode::<Size>(&bytes[Size::get_size_of().as_usize()..])),))
286                } else {
287                    Err(ByteVecError::BadSizeDecodeError {
288                        expected: BVExpectedSize::EqualTo(
289                            Size::get_size_of().as_usize() + size.as_usize()),
290                        actual: bytes.len()
291                    })
292                }
293            }
294        }
295    };
296
297    // Lots of doubled code to implement recursion by dropping the first element each iteration,
298    // so the first operation has to be done outside the macro loop, repeating the code
299    ($t:ident: $elem:ident, $($_t:ident: $_elem:ident),*) => {
300        impl<$t, $($_t,)*> ByteEncodable for ($t, $($_t),*)
301            where $t: ByteEncodable, $($_t: ByteEncodable),*
302        {
303            fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
304                let &(ref $elem, $(ref $_elem),*) = self;
305                (&($elem, $($_elem),*)).get_size::<Size>()
306            }
307
308            fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
309                let &(ref $elem, $(ref $_elem),*) = self;
310                (&($elem, $($_elem),*)).encode::<Size>()
311            }
312        }
313
314        impl<'a, $t, $($_t,)*> ByteEncodable for &'a (&'a $t, $(&'a $_t),*)
315            where $t: ByteEncodable, $($_t: ByteEncodable),*
316        {
317            fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
318                let &&($elem, $($_elem),*) = self;
319                let mut size = Some(Size::from_usize(0));
320
321                size = size.and_then(|size: Size|
322                    $elem.get_size::<Size>().and_then(|elem_size|
323                        size.checked_add(elem_size).and_then(
324                            |acc_size| acc_size.checked_add(Size::get_size_of())
325                        )
326                    )
327                );
328                $(
329                    size = size.and_then(|size: Size|
330                        $_elem.get_size::<Size>().and_then(|elem_size|
331                            size.checked_add(elem_size).and_then(
332                                |acc_size| acc_size.checked_add(Size::get_size_of())
333                            )
334                        )
335                    );
336                )*
337                size
338            }
339
340            fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
341                if self.get_size::<Size>().is_some() {
342                    let &&($elem, $($_elem),*) = self;
343                    let mut bytes = Vec::new();
344                    bytes.extend_from_slice(&try!(
345                        $elem.get_size::<Size>().unwrap().encode::<Size>()));
346                    $(
347                        bytes.extend_from_slice(&try!(
348                            $_elem.get_size::<Size>().unwrap().encode::<Size>()));
349                    )*
350                    bytes.extend_from_slice(&try!($elem.encode::<Size>()));
351                    $(
352                        bytes.extend_from_slice(&try!($_elem.encode::<Size>()));
353                    )*
354                    Ok(bytes)
355                } else {
356                    Err(ByteVecError::OverflowError)
357                }
358            }
359        }
360
361        #[allow(unused_assignments)]
362        impl<$t, $($_t,)*> ByteDecodable for ($t, $($_t),*)
363            where $t: ByteDecodable, $($_t: ByteDecodable),*
364        {
365            fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<($t, $($_t),*)>
366                where Size: BVSize + ByteDecodable
367            {
368                let mut index = 0;
369                let mut sizes = ::std::collections::HashMap::new();
370
371                if bytes.len() >= Size::get_size_of().as_usize() {
372                    sizes.insert(stringify!($elem),
373                        try!(Size::decode::<Size>(&bytes[..Size::get_size_of().as_usize()])));
374                    index += Size::get_size_of().as_usize();
375                }
376                else {
377                    return Err(ByteVecError::BadSizeDecodeError {
378                        expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize() + index),
379                        actual: bytes.len()
380                    });
381                }
382                $(
383                    if bytes[index..].len() >= Size::get_size_of().as_usize() {
384                        sizes.insert(stringify!($_elem),
385                            try!(Size::decode::<Size>(
386                                &bytes[index..index + Size::get_size_of().as_usize()])));
387                        index += Size::get_size_of().as_usize();
388                    }
389                    else {
390                        return Err(ByteVecError::BadSizeDecodeError {
391                            expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize() + index),
392                            actual: bytes.len()
393                        });
394                    }
395                )*
396
397                let body_size = sizes.values().fold(0, |acc, ref size| acc + size.as_usize());
398                if body_size == bytes[index..].len() {
399                    Ok((
400                        {
401                            let elem = try!($t::decode::<Size>(
402                                &bytes[index..index + sizes[stringify!($elem)].as_usize()]));
403                            index += sizes[stringify!($elem)].as_usize();
404                            elem
405                        },
406                        $({
407                            let elem = try!($_t::decode::<Size>(
408                                &bytes[index..index + sizes[stringify!($_elem)].as_usize()]));
409                            index += sizes[stringify!($_elem)].as_usize();
410                            elem
411                        }),*
412                    ))
413                } else {
414                    Err(ByteVecError::BadSizeDecodeError {
415                        expected: BVExpectedSize::EqualTo(
416                            Size::get_size_of().as_usize() * sizes.len() + body_size),
417                        actual: bytes.len()
418                    })
419                }
420            }
421        }
422
423        tuple_impls!($($_t: $_elem),*);
424    }
425}
426
427tuple_impls! {
428    A: a,
429    B: b,
430    C: c,
431    D: d,
432    E: e,
433    F: f,
434    G: g,
435    H: h,
436    I: i,
437    J: j,
438    K: k,
439    L: l
440}
441
442impl ByteEncodable for () {
443    fn get_size<Size>(&self) -> Option<Size>
444        where Size: BVSize + ByteEncodable
445    {
446        Some(Size::from_usize(0))
447    }
448
449    fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
450        where Size: BVSize + ByteEncodable
451    {
452        // Send only size of 0
453        Size::from_usize(0).encode::<Size>()
454    }
455}
456
457impl ByteDecodable for () {
458    fn decode<Size>(_: &[u8]) -> BVDecodeResult<()>
459        where Size: BVSize + ByteDecodable
460    {
461        Ok(())
462    }
463}