cbor/
encoder.rs

1// This Source Code Form is subject to the terms of
2// the Mozilla Public License, v. 2.0. If a copy of
3// the MPL was not distributed with this file, You
4// can obtain one at http://mozilla.org/MPL/2.0/.
5
6//! CBOR ([RFC 7049](http://tools.ietf.org/html/rfc7049))
7//! encoder implementation.
8//!
9//! This module provides an `Encoder` to directly encode Rust types into
10//! CBOR, and a `GenericEncoder` which encodes a `Value` into CBOR.
11//!
12//! # Example 1: Direct encoding
13//!
14//! ```
15//! extern crate cbor;
16//! extern crate rustc_serialize;
17//!
18//! use cbor::Encoder;
19//! use rustc_serialize::hex::FromHex;
20//! use std::io::Cursor;
21//!
22//! fn main() {
23//!     let mut e = Encoder::new(Cursor::new(Vec::new()));
24//!     e.u16(1000).unwrap();
25//!     assert_eq!("1903e8".from_hex().unwrap(), e.into_writer().into_inner())
26//! }
27//! ```
28//!
29//! # Example 2: Direct encoding (indefinite string)
30//!
31//! ```
32//! extern crate cbor;
33//! extern crate rustc_serialize;
34//!
35//! use cbor::Encoder;
36//! use rustc_serialize::hex::FromHex;
37//! use std::io::Cursor;
38//!
39//! fn main() {
40//!     let mut e = Encoder::new(Cursor::new(Vec::new()));
41//!     e.text_iter(vec!["strea", "ming"].into_iter()).unwrap();
42//!     let output = "7f657374726561646d696e67ff".from_hex().unwrap();
43//!     assert_eq!(output, e.into_writer().into_inner())
44//! }
45//! ```
46//!
47//! # Example 3: Direct encoding (nested array)
48//!
49//! ```
50//! extern crate cbor;
51//! extern crate rustc_serialize;
52//!
53//! use cbor::Encoder;
54//! use rustc_serialize::hex::FromHex;
55//! use std::io::Cursor;
56//!
57//! fn main() {
58//!     let mut e = Encoder::new(Cursor::new(Vec::new()));
59//!     e.array(3)
60//!      .and(e.u8(1))
61//!      .and(e.array(2)).and(e.u8(2)).and(e.u8(3))
62//!      .and(e.array(2)).and(e.u8(4)).and(e.u8(5))
63//!      .unwrap();
64//!     let output = "8301820203820405".from_hex().unwrap();
65//!     assert_eq!(output, e.into_writer().into_inner())
66//! }
67//! ```
68
69use byteorder::{BigEndian, WriteBytesExt};
70use std::io;
71use std::error::Error;
72use std::fmt;
73use types::{Tag, Type};
74use value::{Bytes, Int, Key, Simple, Text, Value};
75
76// Encoder Error Type ///////////////////////////////////////////////////////
77
78pub type EncodeResult = Result<(), EncodeError>;
79
80#[derive(Debug)]
81pub enum EncodeError {
82    /// Some I/O error
83    IoError(io::Error),
84    /// The end of file has been encountered unexpectedly
85    UnexpectedEOF,
86    /// The provided `Simple` value is neither unassigned nor reserved
87    InvalidSimpleValue(Simple),
88    /// Certain values (e.g. `Value::Break`) are not legal to encode as
89    /// independent units. Attempting to do so will trigger this error.
90    InvalidValue(Value),
91    /// Some other error.
92    Other(Box<Error + Send + Sync>)
93}
94
95impl fmt::Display for EncodeError {
96    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
97        match *self {
98            EncodeError::IoError(ref e)            => write!(f, "EncodeError: I/O error: {}", *e),
99            EncodeError::UnexpectedEOF             => write!(f, "EncodeError: unexpected end-of-file"),
100            EncodeError::InvalidValue(ref v)       => write!(f, "EncodeError: invalid value {:?}", v),
101            EncodeError::InvalidSimpleValue(ref s) => write!(f, "EncodeError: invalid simple value {:?}", s),
102            EncodeError::Other(ref e)              => write!(f, "EncodeError: other error: {}", e)
103        }
104    }
105}
106
107impl Error for EncodeError {
108    fn description(&self) -> &str {
109        match *self {
110            EncodeError::IoError(_)            => "i/o error",
111            EncodeError::UnexpectedEOF         => "unexpected eof",
112            EncodeError::InvalidValue(_)       => "invalid value",
113            EncodeError::InvalidSimpleValue(_) => "invalid simple value",
114            EncodeError::Other(_)              => "other error"
115        }
116    }
117
118    fn cause(&self) -> Option<&Error> {
119        match *self {
120            EncodeError::IoError(ref e) => Some(e),
121            EncodeError::Other(ref e)   => Some(&**e),
122            _                           => None
123        }
124    }
125}
126
127impl From<io::Error> for EncodeError {
128    fn from(e: io::Error) -> EncodeError {
129        EncodeError::IoError(e)
130    }
131}
132
133// Encoder //////////////////////////////////////////////////////////////////
134
135/// The actual encoder type definition
136pub struct Encoder<W> {
137    writer: W
138}
139
140impl<W: WriteBytesExt> Encoder<W> {
141    pub fn new(w: W) -> Encoder<W> {
142        Encoder { writer: w }
143    }
144
145    pub fn into_writer(self) -> W {
146        self.writer
147    }
148
149    pub fn writer(&mut self) -> &mut W {
150        &mut self.writer
151    }
152
153    pub fn u8(&mut self, x: u8) -> EncodeResult {
154        let ref mut w = self.writer;
155        match x {
156            0...23 => w.write_u8(x).map_err(From::from),
157            _      => w.write_u8(24).and(w.write_u8(x)).map_err(From::from)
158        }
159    }
160
161    pub fn u16(&mut self, x: u16) -> EncodeResult {
162        let ref mut w = self.writer;
163        match x {
164            0...23    => w.write_u8(x as u8).map_err(From::from),
165            24...0xFF => w.write_u8(24).and(w.write_u8(x as u8)).map_err(From::from),
166            _         => w.write_u8(25).and(w.write_u16::<BigEndian>(x)).map_err(From::from)
167        }
168    }
169
170    pub fn u32(&mut self, x: u32) -> EncodeResult {
171        let ref mut w = self.writer;
172        match x {
173            0...23         => w.write_u8(x as u8).map_err(From::from),
174            24...0xFF      => w.write_u8(24).and(w.write_u8(x as u8)).map_err(From::from),
175            0x100...0xFFFF => w.write_u8(25).and(w.write_u16::<BigEndian>(x as u16)).map_err(From::from),
176            _              => w.write_u8(26).and(w.write_u32::<BigEndian>(x)).map_err(From::from)
177        }
178    }
179
180    pub fn u64(&mut self, x: u64) -> EncodeResult {
181        let ref mut w = self.writer;
182        match x {
183            0...23                => w.write_u8(x as u8).map_err(From::from),
184            24...0xFF             => w.write_u8(24).and(w.write_u8(x as u8)).map_err(From::from),
185            0x100...0xFFFF        => w.write_u8(25).and(w.write_u16::<BigEndian>(x as u16)).map_err(From::from),
186            0x100000...0xFFFFFFFF => w.write_u8(26).and(w.write_u32::<BigEndian>(x as u32)).map_err(From::from),
187            _                     => w.write_u8(27).and(w.write_u64::<BigEndian>(x)).map_err(From::from)
188        }
189    }
190
191    pub fn i8(&mut self, x: i8) -> EncodeResult {
192        if x >= 0 {
193            self.u8(x as u8)
194        } else {
195            let ref mut w = self.writer;
196            match (-1 - x) as u8 {
197                n @ 0...23 => w.write_u8(0b001_00000 | n).map_err(From::from),
198                n          => w.write_u8(0b001_00000 | 24).and(w.write_u8(n)).map_err(From::from)
199            }
200        }
201    }
202
203    pub fn i16(&mut self, x: i16) -> EncodeResult {
204        if x >= 0 {
205            self.u16(x as u16)
206        } else {
207            let ref mut w = self.writer;
208            match (-1 - x) as u16 {
209                n @ 0...23    => w.write_u8(0b001_00000 | n as u8).map_err(From::from),
210                n @ 24...0xFF => w.write_u8(0b001_00000 | 24).and(w.write_u8(n as u8)).map_err(From::from),
211                n             => w.write_u8(0b001_00000 | 25).and(w.write_u16::<BigEndian>(n)).map_err(From::from)
212            }
213        }
214    }
215
216    pub fn i32(&mut self, x: i32) -> EncodeResult {
217        if x >= 0 {
218            self.u32(x as u32)
219        } else {
220            let ref mut w = self.writer;
221            match (-1 - x) as u32 {
222                n @ 0...23         => w.write_u8(0b001_00000 | n as u8).map_err(From::from),
223                n @ 24...0xFF      => w.write_u8(0b001_00000 | 24).and(w.write_u8(n as u8)).map_err(From::from),
224                n @ 0x100...0xFFFF => w.write_u8(0b001_00000 | 25).and(w.write_u16::<BigEndian>(n as u16)).map_err(From::from),
225                n                  => w.write_u8(0b001_00000 | 26).and(w.write_u32::<BigEndian>(n)).map_err(From::from)
226            }
227        }
228    }
229
230    pub fn i64(&mut self, x: i64) -> EncodeResult {
231        if x >= 0 {
232            self.u64(x as u64)
233        } else {
234            let ref mut w = self.writer;
235            match (-1 - x) as u64 {
236                n @ 0...23                => w.write_u8(0b001_00000 | n as u8).map_err(From::from),
237                n @ 24...0xFF             => w.write_u8(0b001_00000 | 24).and(w.write_u8(n as u8)).map_err(From::from),
238                n @ 0x100...0xFFFF        => w.write_u8(0b001_00000 | 25).and(w.write_u16::<BigEndian>(n as u16)).map_err(From::from),
239                n @ 0x100000...0xFFFFFFFF => w.write_u8(0b001_00000 | 26).and(w.write_u32::<BigEndian>(n as u32)).map_err(From::from),
240                n                         => w.write_u8(0b001_00000 | 27).and(w.write_u64::<BigEndian>(n)).map_err(From::from)
241            }
242        }
243    }
244
245    pub fn int(&mut self, x: Int) -> EncodeResult {
246        match x {
247            Int::Pos(v) => self.u64(v),
248            Int::Neg(v) => {
249                let ref mut w = self.writer;
250                match v {
251                    n @ 0...23                => w.write_u8(0b001_00000 | n as u8).map_err(From::from),
252                    n @ 24...0xFF             => w.write_u8(0b001_00000 | 24).and(w.write_u8(n as u8)).map_err(From::from),
253                    n @ 0x100...0xFFFF        => w.write_u8(0b001_00000 | 25).and(w.write_u16::<BigEndian>(n as u16)).map_err(From::from),
254                    n @ 0x100000...0xFFFFFFFF => w.write_u8(0b001_00000 | 26).and(w.write_u32::<BigEndian>(n as u32)).map_err(From::from),
255                    n                         => w.write_u8(0b001_00000 | 27).and(w.write_u64::<BigEndian>(n)).map_err(From::from)
256                }
257            }
258        }
259    }
260
261    pub fn f32(&mut self, x: f32) -> EncodeResult {
262        self.writer.write_u8(0b111_00000 | 26)
263            .and(self.writer.write_f32::<BigEndian>(x))
264            .map_err(From::from)
265    }
266
267    pub fn f64(&mut self, x: f64) -> EncodeResult {
268        self.writer.write_u8(0b111_00000 | 27)
269            .and(self.writer.write_f64::<BigEndian>(x))
270            .map_err(From::from)
271    }
272
273    pub fn bool(&mut self, x: bool) -> EncodeResult {
274        self.writer.write_u8(0b111_00000 | if x {21} else {20}).map_err(From::from)
275    }
276
277    pub fn simple(&mut self, x: Simple) -> EncodeResult {
278        let ref mut w = self.writer;
279        match x {
280            Simple::Unassigned(n) => match n {
281                0...19 | 28...30 => w.write_u8(0b111_00000 | n).map_err(From::from),
282                32...255         => w.write_u8(0b111_00000 | 24).and(w.write_u8(n)).map_err(From::from),
283                _                => Err(EncodeError::InvalidSimpleValue(x))
284            },
285            Simple::Reserved(n) => match n {
286                0...31 => w.write_u8(0b111_00000 | 24).and(w.write_u8(n)).map_err(From::from),
287                _      => Err(EncodeError::InvalidSimpleValue(x))
288            }
289        }
290    }
291
292    pub fn bytes(&mut self, x: &[u8]) -> EncodeResult {
293        self.type_len(Type::Bytes, x.len() as u64)
294            .and(self.writer.write_all(x).map_err(From::from))
295    }
296
297    /// Indefinite byte string encoding. (RFC 7049 section 2.2.2)
298    pub fn bytes_iter<'r, I: Iterator<Item=&'r [u8]>>(&mut self, iter: I) -> EncodeResult {
299        self.writer.write_u8(0b010_11111)?;
300        for x in iter {
301            self.bytes(x)?
302        }
303        self.writer.write_u8(0b111_11111).map_err(From::from)
304    }
305
306    pub fn text(&mut self, x: &str) -> EncodeResult {
307        self.type_len(Type::Text, x.len() as u64)
308            .and(self.writer.write_all(x.as_bytes()).map_err(From::from))
309    }
310
311    /// Indefinite string encoding. (RFC 7049 section 2.2.2)
312    pub fn text_iter<'r, I: Iterator<Item=&'r str>>(&mut self, iter: I) -> EncodeResult {
313        self.writer.write_u8(0b011_11111)?;
314        for x in iter {
315            self.text(x)?
316        }
317        self.writer.write_u8(0b111_11111).map_err(From::from)
318    }
319
320    pub fn null(&mut self) -> EncodeResult {
321        self.writer.write_u8(0b111_00000 | 22).map_err(From::from)
322    }
323
324    pub fn undefined(&mut self) -> EncodeResult {
325        self.writer.write_u8(0b111_00000 | 23).map_err(From::from)
326    }
327
328    pub fn tag(&mut self, x: Tag) -> EncodeResult {
329        self.type_len(Type::Tagged, x.to())
330    }
331
332    pub fn array(&mut self, len: usize) -> EncodeResult {
333        self.type_len(Type::Array, len as u64)
334    }
335
336    /// Indefinite array encoding. (RFC 7049 section 2.2.1)
337    pub fn array_begin(&mut self) -> EncodeResult {
338        self.writer.write_u8(0b100_11111).map_err(From::from)
339    }
340
341    /// End of indefinite array encoding. (RFC 7049 section 2.2.1)
342    pub fn array_end(&mut self) -> EncodeResult {
343        self.writer.write_u8(0b111_11111).map_err(From::from)
344    }
345
346    pub fn object(&mut self, len: usize) -> EncodeResult {
347        self.type_len(Type::Object, len as u64)
348    }
349
350    /// Indefinite object encoding. (RFC 7049 section 2.2.1)
351    pub fn object_begin(&mut self) -> EncodeResult {
352        self.writer.write_u8(0b101_11111).map_err(From::from)
353    }
354
355    /// End of indefinite object encoding. (RFC 7049 section 2.2.1)
356    pub fn object_end(&mut self) -> EncodeResult {
357        self.writer.write_u8(0b111_11111).map_err(From::from)
358    }
359
360    fn type_len(&mut self, t: Type, x: u64) -> EncodeResult {
361        let ref mut w = self.writer;
362        match x {
363            0...23                => w.write_u8(t.major() << 5 | x as u8).map_err(From::from),
364            24...0xFF             => w.write_u8(t.major() << 5 | 24).and(w.write_u8(x as u8)).map_err(From::from),
365            0x100...0xFFFF        => w.write_u8(t.major() << 5 | 25).and(w.write_u16::<BigEndian>(x as u16)).map_err(From::from),
366            0x100000...0xFFFFFFFF => w.write_u8(t.major() << 5 | 26).and(w.write_u32::<BigEndian>(x as u32)).map_err(From::from),
367            _                     => w.write_u8(t.major() << 5 | 27).and(w.write_u64::<BigEndian>(x)).map_err(From::from)
368        }
369    }
370}
371
372// Generic Encoder //////////////////////////////////////////////////////////
373
374/// A generic encoder encodes a `Value`.
375pub struct GenericEncoder<W> {
376    encoder: Encoder<W>
377}
378
379impl<W: WriteBytesExt> GenericEncoder<W> {
380    pub fn new(w: W) -> GenericEncoder<W> {
381        GenericEncoder { encoder: Encoder::new(w) }
382    }
383
384    pub fn from_encoder(e: Encoder<W>) -> GenericEncoder<W> {
385        GenericEncoder { encoder: e }
386    }
387
388    pub fn into_inner(self) -> Encoder<W> {
389        self.encoder
390    }
391
392    pub fn borrow_mut(&mut self) -> &mut Encoder<W> {
393        &mut self.encoder
394    }
395
396    pub fn value(&mut self, x: &Value) -> EncodeResult {
397        match *x {
398            Value::Array(ref vv) => {
399                self.encoder.array(vv.len())?;
400                for v in vv {
401                    self.value(v)?
402                }
403                Ok(())
404            }
405            Value::Bytes(Bytes::Bytes(ref bb))  => self.encoder.bytes(&bb[..]),
406            Value::Bytes(Bytes::Chunks(ref bb)) => self.encoder.bytes_iter(bb.iter().map(|v| &v[..])),
407            Value::Text(Text::Text(ref txt))    => self.encoder.text(txt),
408            Value::Text(Text::Chunks(ref txt))  => self.encoder.text_iter(txt.iter().map(|v| &v[..])),
409            Value::Map(ref m) => {
410                self.encoder.object(m.len())?;
411                for (k, v) in m {
412                    self.key(k).and(self.value(v))?
413                }
414                Ok(())
415            }
416            Value::Tagged(t, ref val) => {
417                self.encoder.tag(t)?;
418                self.value(&*val)
419            }
420            Value::Undefined => self.encoder.undefined(),
421            Value::Null      => self.encoder.null(),
422            Value::Simple(s) => self.encoder.simple(s),
423            Value::Bool(b)   => self.encoder.bool(b),
424            Value::U8(n)     => self.encoder.u8(n),
425            Value::U16(n)    => self.encoder.u16(n),
426            Value::U32(n)    => self.encoder.u32(n),
427            Value::U64(n)    => self.encoder.u64(n),
428            Value::F32(n)    => self.encoder.f32(n),
429            Value::F64(n)    => self.encoder.f64(n),
430            Value::I8(n)     => self.encoder.i8(n),
431            Value::I16(n)    => self.encoder.i16(n),
432            Value::I32(n)    => self.encoder.i32(n),
433            Value::I64(n)    => self.encoder.i64(n),
434            Value::Int(n)    => self.encoder.int(n),
435            Value::Break     => Err(EncodeError::InvalidValue(Value::Break))
436        }
437    }
438
439    fn key(&mut self, x: &Key) -> EncodeResult {
440        match *x {
441            Key::Bool(b) => self.encoder.bool(b),
442            Key::Int(n)  => self.encoder.int(n),
443            Key::Bytes(Bytes::Bytes(ref bb))  => self.encoder.bytes(&bb[..]),
444            Key::Bytes(Bytes::Chunks(ref bb)) => self.encoder.bytes_iter(bb.iter().map(|v| &v[..])),
445            Key::Text(Text::Text(ref txt))    => self.encoder.text(txt),
446            Key::Text(Text::Chunks(ref txt))  => self.encoder.text_iter(txt.iter().map(|v| &v[..]))
447        }
448    }
449}
450
451// Tests ////////////////////////////////////////////////////////////////////
452
453#[cfg(test)]
454mod tests {
455    use rustc_serialize::hex::FromHex;
456    use std::{f32, f64};
457    use std::io::Cursor;
458    use super::*;
459    use types::Tag;
460    use value::Simple;
461
462    #[test]
463    fn unsigned() {
464        encoded("00", |mut e| e.u8(0));
465        encoded("01", |mut e| e.u8(1));
466        encoded("0a", |mut e| e.u8(10));
467        encoded("17", |mut e| e.u8(23));
468        encoded("1818", |mut e| e.u8(24));
469        encoded("1819", |mut e| e.u8(25));
470        encoded("1864", |mut e| e.u8(100));
471        encoded("1903e8", |mut e| e.u16(1000));
472        encoded("1a000f4240", |mut e| e.u32(1000000));
473        encoded("1b000000e8d4a51000", |mut e| e.u64(1000000000000));
474        encoded("1bffffffffffffffff", |mut e| e.u64(18446744073709551615))
475    }
476
477    #[test]
478    fn signed() {
479        encoded("20", |mut e| e.i8(-1));
480        encoded("29", |mut e| e.i8(-10));
481        encoded("3863", |mut e| e.i8(-100));
482        encoded("3901f3", |mut e| e.i16(-500));
483        encoded("3903e7", |mut e| e.i16(-1000));
484        encoded("3a00053d89", |mut e| e.i32(-343434));
485        encoded("3b000000058879da85", |mut e| e.i64(-23764523654))
486    }
487
488    #[test]
489    fn bool() {
490        encoded("f4", |mut e| e.bool(false));
491        encoded("f5", |mut e| e.bool(true))
492    }
493
494    #[test]
495    fn simple() {
496        encoded("f0", |mut e| e.simple(Simple::Unassigned(16)));
497        encoded("f818", |mut e| e.simple(Simple::Reserved(24)));
498        encoded("f8ff", |mut e| e.simple(Simple::Unassigned(255)))
499    }
500
501    #[test]
502    fn float() {
503        encoded("fa47c35000", |mut e| e.f32(100000.0));
504        encoded("fa7f7fffff", |mut e| e.f32(3.4028234663852886e+38));
505        encoded("fbc010666666666666", |mut e| e.f64(-4.1));
506
507        encoded("fa7f800000", |mut e| e.f32(f32::INFINITY));
508        encoded("faff800000", |mut e| e.f32(-f32::INFINITY));
509        encoded("fa7fc00000", |mut e| e.f32(f32::NAN));
510
511        encoded("fb7ff0000000000000", |mut e| e.f64(f64::INFINITY));
512        encoded("fbfff0000000000000", |mut e| e.f64(-f64::INFINITY));
513        encoded("fb7ff8000000000000", |mut e| e.f64(f64::NAN));
514    }
515
516    #[test]
517    fn bytes() {
518        encoded("4401020304", |mut e| e.bytes(&vec![1,2,3,4][..]));
519    }
520
521    #[test]
522    fn text() {
523        encoded("62c3bc", |mut e| e.text("\u{00fc}"));
524        encoded("781f64667364667364660d0a7364660d0a68656c6c6f0d0a736466736673646673", |mut e| {
525            e.text("dfsdfsdf\r\nsdf\r\nhello\r\nsdfsfsdfs")
526        });
527    }
528
529    #[test]
530    fn indefinite_text() {
531        encoded("7f657374726561646d696e67ff", |mut e| {
532            e.text_iter(vec!["strea", "ming"].into_iter())
533        })
534    }
535
536    #[test]
537    fn indefinite_bytes() {
538        encoded("5f457374726561446d696e67ff", |mut e| {
539            e.bytes_iter(vec!["strea".as_bytes(), "ming".as_bytes()].into_iter())
540        })
541    }
542
543    #[test]
544    fn option() {
545        encoded("f6", |mut e| e.null())
546    }
547
548    #[test]
549    fn tagged() {
550        encoded("c11a514b67b0", |mut e| {
551            e.tag(Tag::Timestamp)?;
552            e.u32(1363896240)
553        })
554    }
555
556    #[test]
557    fn array() {
558        encoded("83010203", |mut e| {
559            e.array(3)?;
560            e.u32(1)?;
561            e.u32(2)?;
562            e.u32(3)
563        });
564        encoded("8301820203820405", |mut e| {
565            e.array(3)
566             .and(e.u8(1))
567             .and(e.array(2))
568                .and(e.u8(2))
569                .and(e.u8(3))
570             .and(e.array(2))
571                .and(e.u8(4))
572                .and(e.u8(5))
573        })
574    }
575
576    #[test]
577    fn indefinite_array() {
578        encoded("9f018202039f0405ffff", |mut e| {
579            e.array_begin()
580             .and(e.u8(1))
581             .and(e.array(2))
582                .and(e.u8(2))
583                .and(e.u8(3))
584             .and(e.array_begin())
585                .and(e.u8(4))
586                .and(e.u8(5))
587                .and(e.array_end())
588            .and(e.array_end())
589        });
590        encoded("9f01820203820405ff", |mut e| {
591            e.array_begin()
592             .and(e.u8(1))
593             .and(e.array(2))
594                .and(e.u8(2))
595                .and(e.u8(3))
596             .and(e.array(2))
597                .and(e.u8(4))
598                .and(e.u8(5))
599            .and(e.array_end())
600        });
601        encoded("83018202039f0405ff", |mut e| {
602            e.array(3)
603             .and(e.u8(1))
604             .and(e.array(2))
605                .and(e.u8(2))
606                .and(e.u8(3))
607             .and(e.array_begin())
608                .and(e.u8(4))
609                .and(e.u8(5))
610                .and(e.array_end())
611        });
612        encoded("83019f0203ff820405", |mut e| {
613            e.array(3)
614             .and(e.u8(1))
615             .and(e.array_begin())
616                .and(e.u8(2))
617                .and(e.u8(3))
618                .and(e.array_end())
619             .and(e.array(2))
620                .and(e.u8(4))
621                .and(e.u8(5))
622        })
623    }
624
625    #[test]
626    fn object() {
627        encoded("a26161016162820203", |mut e| {
628            e.object(2)?;
629            e.text("a").and(e.u8(1))?;
630            e.text("b").and(e.array(2)).and(e.u8(2)).and(e.u8(3))
631        })
632    }
633
634    #[test]
635    fn indefinite_object() {
636        encoded("bf6346756ef563416d7421ff", |mut e| {
637            e.object_begin()
638             .and(e.text("Fun"))
639             .and(e.bool(true))
640             .and(e.text("Amt"))
641             .and(e.i8(-2))
642             .and(e.object_end())
643        })
644    }
645
646    fn encoded<F>(expected: &str, mut f: F)
647    where F: FnMut(Encoder<Cursor<&mut [u8]>>) -> EncodeResult
648    {
649        let mut buffer = vec![0u8; 128];
650        assert!(f(Encoder::new(Cursor::new(&mut buffer[..]))).is_ok());
651        assert_eq!(&expected.from_hex().unwrap()[..], &buffer[0 .. expected.len() / 2])
652    }
653}