zero_formatter/
object.rs

1use error::*;
2use formatter::*;
3
4use std::io::Seek;
5use byteorder::{ReadBytesExt, WriteBytesExt};
6
7/// `struct_formatter` define sturct type and provide sequential fields formatter.
8/// But, `struct_formatter` does not support [versioning](https://github.com/neuecc/ZeroFormatter/tree/1.6.0#versioning).
9///
10/// ```
11/// # #[macro_use] extern crate zero_formatter;
12/// # extern crate byteorder;
13/// # use zero_formatter::*;
14/// # use std::io::{Seek, SeekFrom, Read, Write, Cursor, Result};
15/// # use byteorder::{ReadBytesExt, WriteBytesExt};
16/// #
17/// # declare_buffer! { Buffer }
18/// #
19/// struct_formatter! {
20///     #[target(Buffer<Cursor<Vec<u8>>>)]
21///     StructSample {
22///         a: i32,
23///         b: i64
24///     }
25/// }
26///
27/// # fn example() -> Result<()> {
28/// # let mut writer = Buffer::new(Cursor::new(Vec::new()));
29/// try!(writer.serialize(0, StructSample { a: 1, b: 2 }));
30/// # Ok(())
31/// # }
32/// #
33/// # fn main() {
34/// # example();
35/// # }
36/// ```
37#[macro_export]
38macro_rules! struct_formatter {
39    (#[target($buffer:ty)]
40    $name:ident {
41        $($field_name:ident: $field_type:ty),*
42    }) => {
43        #[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
44        pub struct $name {
45            $(pub $field_name: $field_type),*
46        }
47
48        impl Formatter<$name> for $buffer {
49
50            fn serialize(&mut self, offset: u64, value: $name) -> ZeroFormatterResult<i32> {
51                let mut byte_size: i32 = 0;
52
53                $(
54                let $field_name = try!(self.serialize(offset + (byte_size as u64), value.$field_name));
55                byte_size += $field_name;
56                )*
57
58                Ok(byte_size)
59            }
60
61            fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<$name> {
62
63                $(
64                let $field_name: $field_type = try!(self.deserialize(offset));
65                )*
66
67                Ok($name { $($field_name: $field_name),* })
68            }
69        }
70
71        has_value_formatter! {
72            #[target($buffer)]
73            $name
74        }
75    }
76}
77
78impl<R, A1, A2> Formatter<(A1, A2)> for R
79  where R: Seek + ReadBytesExt + WriteBytesExt + Formatter<A1> + Formatter<A2> {
80
81    fn serialize(&mut self, offset: u64, value: (A1, A2)) -> ZeroFormatterResult<i32> {
82        let r1 = try!(self.serialize(offset, value.0));
83        let r2 = try!(self.serialize(offset + (r1 as u64), value.1));
84        Ok(r1 + r2)
85    }
86
87    fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<(A1, A2)> {
88        let a1: A1 = try!(self.deserialize(offset));
89        let a2: A2 = try!(self.deserialize(offset));
90        Ok((a1, a2))
91    }
92}
93
94/// `object_formatter` define struct type and provide formatter.
95/// `object_formatter` support [versioning](https://github.com/neuecc/ZeroFormatter/tree/1.6.0#versioning).
96///
97/// ```
98/// # #[macro_use] extern crate zero_formatter;
99/// # extern crate byteorder;
100/// # use zero_formatter::*;
101/// # use std::io::{Seek, SeekFrom, Read, Write, Cursor, Result};
102/// # use byteorder::{ReadBytesExt, WriteBytesExt};
103/// #
104/// # declare_buffer! { Buffer }
105/// #
106/// object_formatter! {
107///     #[target(Buffer<Cursor<Vec<u8>>>)]
108///     ObjectSample {
109///         0; a: i32,
110///         1; b: i64
111///     }
112/// }
113///
114/// # fn example() -> Result<()> {
115/// # let mut writer = Buffer::new(Cursor::new(Vec::new()));
116/// try!(writer.serialize(0, ObjectSample { a: 1, b: 2 }));
117/// # Ok(())
118/// # }
119/// #
120/// # fn main() {
121/// # example();
122/// # }
123/// ```
124#[macro_export]
125macro_rules! object_formatter {
126    (#[target($buffer:ty)]
127    $name:ident {
128        $($index:expr; $field_name:ident: $field_type:ty),*
129    }) => {
130        #[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
131        pub struct $name {
132            $(pub $field_name: $field_type),*
133        }
134
135        impl Formatter<$name> for $buffer {
136
137            fn serialize(&mut self, offset: u64, value: $name) -> ZeroFormatterResult<i32> {
138                let last_index: i32 = *([$($index),*].iter().max().unwrap());
139                let mut byte_size: i32 = 4 + 4 + 4 * (last_index + 1);
140
141                try!(self.serialize(offset + 4, last_index));
142
143                $(
144                try!(self.serialize(offset + 4 + 4 + 4 * $index, (offset as i32) + byte_size));
145                let $field_name = try!(self.serialize(offset + (byte_size as u64), value.$field_name));
146                byte_size += $field_name;
147                )*
148
149                try!(self.serialize(offset, byte_size));
150                try!(self.seek(SeekFrom::Start(offset + (byte_size as u64))));
151                Ok(byte_size)
152            }
153
154            fn deserialize(&mut self, offset: &mut u64) -> ZeroFormatterResult<$name> {
155
156                let start_offset: u64 = *offset;
157                let byte_size = try!(util::check_non_null(self, offset));
158                let last_index: i32 = try!(self.deserialize(offset));
159
160                $(
161                let $field_name: $field_type = try!(if $index <= last_index {
162                    *offset = start_offset + 4 + 4 + 4 * $index;
163                    let o: i32 = try!(self.deserialize(offset));
164                    if o == 0 {
165                        Ok(Default::default())
166                    } else {
167                        *offset = o as u64;
168                        self.deserialize(offset)
169                    }
170                } else {
171                    Ok(Default::default())
172                });
173                )*
174
175                *offset = start_offset + (byte_size as u64);
176                Ok($name { $($field_name: $field_name),* })
177            }
178        }
179
180        option_formatter! {
181            #[target($buffer)]
182            $name
183        }
184    }
185}
186
187#[cfg(test)]
188mod tests {
189
190    use std::io::Cursor;
191    use std::io::{Seek, SeekFrom};
192    use error::*;
193    use formatter::*;
194    use util;
195
196    object_formatter! {
197        #[target(Cursor<Vec<u8>>)]
198        O {
199            0; a: i32,
200            1; b: i64
201        }
202    }
203
204    #[test]
205    fn serialize_object() {
206        let mut wtr = Cursor::new(Vec::new());
207        assert_eq!(wtr.serialize(0, O { a: 1, b: 2 }).unwrap(), 28);
208        assert_eq!(wtr.into_inner(), vec![28, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
209    }
210
211    #[test]
212    fn deserialize_object() {
213        let mut rdr = Cursor::new(vec![28, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
214        let mut offset = 0;
215        assert_eq!(O { a: 1, b: 2 }, rdr.deserialize(&mut offset).unwrap());
216    }
217
218    #[test]
219    fn serialize_object_some() {
220        let mut wtr = Cursor::new(Vec::new());
221        assert_eq!(wtr.serialize(0, Some(O { a: 1, b: 2 })).unwrap(), 28);
222        assert_eq!(wtr.into_inner(), vec![28, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
223    }
224
225    #[test]
226    fn deserialize_object_some() {
227        let mut rdr = Cursor::new(vec![28, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
228        let mut offset = 0;
229        assert_eq!(Some(O { a: 1, b: 2 }), rdr.deserialize(&mut offset).unwrap());
230    }
231
232    #[test]
233    fn serialize_object_none() {
234        let mut wtr = Cursor::new(Vec::new());
235        let input: Option<O> = None;
236        assert_eq!(wtr.serialize(0, input).unwrap(), 4);
237        assert_eq!(wtr.into_inner(), vec![0xff, 0xff, 0xff, 0xff]);
238    }
239
240    #[test]
241    fn deserialize_object_none() {
242        let mut rdr = Cursor::new(vec![0xff, 0xff, 0xff, 0xff]);
243        let mut offset = 0;
244        let expected: Option<O> = None;
245        assert_eq!(expected, rdr.deserialize(&mut offset).unwrap());
246    }
247
248    object_formatter! {
249        #[target(Cursor<Vec<u8>>)]
250        O2 {
251            0; a: i32,
252            1; b: i64,
253            2; c: i8
254        }
255    }
256
257    #[test]
258    fn deserialize_object_versioning() {
259        let mut rdr = Cursor::new(vec![28, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
260        let mut offset = 0;
261        assert_eq!(O2 { a: 1, b: 2, c: 0 }, rdr.deserialize(&mut offset).unwrap());
262    }
263
264    struct_formatter! {
265        #[target(Cursor<Vec<u8>>)]
266        S {
267            a: i32,
268            b: i64
269        }
270    }
271
272    #[test]
273    fn serialize_struct() {
274        let mut wtr = Cursor::new(Vec::new());
275        assert_eq!(wtr.serialize(0, S { a: 1, b: 2 }).unwrap(), 12);
276        assert_eq!(wtr.into_inner(), vec![1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
277    }
278
279    #[test]
280    fn deserialize_struct() {
281        let mut rdr = Cursor::new(vec![1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
282        let mut offset = 0;
283        assert_eq!(S { a: 1, b: 2 }, rdr.deserialize(&mut offset).unwrap());
284    }
285
286    #[test]
287    fn serialize_struct_some() {
288        let mut wtr = Cursor::new(Vec::new());
289        assert_eq!(wtr.serialize(0, Some(S { a: 1, b: 2 })).unwrap(), 13);
290        assert_eq!(wtr.into_inner(), vec![1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
291    }
292
293    #[test]
294    fn deserialize_struct_some() {
295        let mut rdr = Cursor::new(vec![1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]);
296        let mut offset = 0;
297        assert_eq!(Some(S { a: 1, b: 2 }), rdr.deserialize(&mut offset).unwrap());
298    }
299
300    #[test]
301    fn serialize_struct_none() {
302        let mut wtr = Cursor::new(Vec::new());
303        let input: Option<S> = None;
304        assert_eq!(wtr.serialize(0, input).unwrap(), 1);
305        assert_eq!(wtr.into_inner(), vec![0]);
306    }
307
308    #[test]
309    fn deserialize_struct_none() {
310        let mut rdr = Cursor::new(vec![0]);
311        let mut offset = 0;
312        let expected: Option<S> = None;
313        assert_eq!(expected, rdr.deserialize(&mut offset).unwrap());
314    }
315
316    #[test]
317    fn serialize_2_tuple() {
318        let mut wtr = Cursor::new(Vec::new());
319        assert_eq!(wtr.serialize(0, (1u8, 2u8)).unwrap(), 2);
320        assert_eq!(wtr.into_inner(), vec![1, 2]);
321    }
322
323    #[test]
324    fn deserialize_2_tuple() {
325        let mut rdr = Cursor::new(vec![1, 2]);
326        let mut offset = 0;
327        assert_eq!((1u8, 2u8), rdr.deserialize(&mut offset).unwrap());
328    }
329}