zero_formatter/
has_value.rs1use 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}