zero_formatter/
has_value.rs

1use error::*;
2use formatter::*;
3
4use std::io::Seek;
5use byteorder::{ReadBytesExt, WriteBytesExt};
6use chrono::{UTC, DateTime};
7use std::time::Duration;
8
9#[macro_export]
10macro_rules! has_value_formatter_methods {
11    ($t:ty) => (
12        fn serialize(&mut self, offset: u64, value: Option<$t>) -> ZeroFormatterResult<i32> {
13            match value {
14                None => {
15                    self.serialize(offset, false)
16                },
17                Some(v) => {
18                    let r1 = try!(self.serialize(offset, true));
19                    let r2 = try!(self.serialize(offset + 1, v));
20                    Ok(r1 + r2)
21                }
22            }
23        }
24
25        fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<Option<$t>> {
26            let has_value: bool = try!(self.deserialize(offset));
27            if has_value {
28                self.deserialize(offset).map(|v| Some(v))
29            }
30            else {
31                Ok(None)
32            }
33        }
34    )
35}
36
37macro_rules! primitive_has_value_formatter {
38    ($($t:ty),*) => ($(
39        impl<R> Formatter<Option<$t>> for R where R: Seek + ReadBytesExt + WriteBytesExt {
40            has_value_formatter_methods! { $t }
41        }
42    )*)
43}
44
45primitive_has_value_formatter! {
46    u8,
47    u16,
48    u32,
49    u64,
50    i8,
51    i16,
52    i32,
53    i64,
54    f32,
55    f64,
56    bool,
57    DateTime<UTC>,
58    Duration
59}
60
61#[macro_export]
62macro_rules! has_value_formatter {
63    (#[target($buffer:ty)]
64    $t:ty
65    ) => (
66        impl Formatter<Option<$t>> for $buffer {
67            has_value_formatter_methods! { $t }
68        }
69    )
70}
71
72#[cfg(test)]
73mod tests {
74
75    use std::io::Cursor;
76    use formatter::*;
77
78    #[test]
79    fn serialize_u8_some() {
80        let mut wtr = Cursor::new(Vec::new());
81        assert_eq!(wtr.serialize(0, Some(1u8)).unwrap(), 2);
82        assert_eq!(wtr.into_inner(), vec![1, 1]);
83    }
84
85    #[test]
86    fn deserialize_u8_some() {
87        let mut rdr = Cursor::new(vec![1, 1]);
88        let mut offset = 0;
89        assert_eq!(Some(1u8), rdr.deserialize(&mut offset).unwrap());
90    }
91
92    #[test]
93    fn serialize_u8_none() {
94        let mut wtr = Cursor::new(Vec::new());
95        let input: Option<u8> = None;
96        assert_eq!(wtr.serialize(0, input).unwrap(), 1);
97        assert_eq!(wtr.into_inner(), vec![0]);
98    }
99
100    #[test]
101    fn deserialize_u8_none() {
102        let mut rdr = Cursor::new(vec![0]);
103        let mut offset = 0;
104        let expected: Option<u8> = None;
105        assert_eq!(expected, rdr.deserialize(&mut offset).unwrap());
106    }
107}