1use 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
76pub type EncodeResult = Result<(), EncodeError>;
79
80#[derive(Debug)]
81pub enum EncodeError {
82 IoError(io::Error),
84 UnexpectedEOF,
86 InvalidSimpleValue(Simple),
88 InvalidValue(Value),
91 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
133pub 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 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 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 pub fn array_begin(&mut self) -> EncodeResult {
338 self.writer.write_u8(0b100_11111).map_err(From::from)
339 }
340
341 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 pub fn object_begin(&mut self) -> EncodeResult {
352 self.writer.write_u8(0b101_11111).map_err(From::from)
353 }
354
355 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
372pub 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#[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}