mpack/
lib.rs

1//! A MessagePack implementation for Rust.
2//!
3//! ~~~ignore
4//! use std::net::TcpStream;
5//! use mpack::{Value, write_value};
6//!
7//! let mut conn = TcpStream::connect("127.0.0.1:8081").unwrap();
8//!
9//! // write values
10//! write(&mut conn, 3 as i32).unwrap();
11//! ~~~
12//!
13//! Reading values is just as easy:
14//!
15//! ~~~ignore
16//! use std::net::TcpStream;
17//! use mpack::{Value, Reader};
18//!
19//! let mut conn = TcpStream::connect("127.0.0.1:8081").unwrap();
20//! let mut reader = Reader::new(conn);
21//!
22//! let value = reader.read_value().unwrap();
23//! // `value` can be inspected with `match` or converted directly with a convenience method
24//! ~~~
25
26#![crate_type = "lib"]
27#![allow(dead_code)]
28
29use std::any::TypeId;
30use std::error::Error;
31use std::slice;
32use std::io::{self, Read, Write};
33use std::string;
34
35mod byte;
36pub mod rpc;
37
38macro_rules! nth_byte(
39    ($x:expr, $n:expr) => ((($x >> ($n * 8)) & 0xFF) as u8)
40);
41
42/// A value that can be sent by `msgpack`.
43#[derive(Clone, PartialEq, Debug)]
44pub enum Value {
45    Nil,
46    Boolean(bool),
47    Uint8(u8),
48    Uint16(u16),
49    Uint32(u32),
50    Uint64(u64),
51    Int8(i8),
52    Int16(i16),
53    Int32(i32),
54    Int64(i64),
55    Float32(f32),
56    Float64(f64),
57    String(string::String),
58    Binary(Vec<u8>),
59    Array(Vec<Value>),
60    Map(ValueMap),
61    Extended(i8, Vec<u8>),
62}
63
64impl Value {
65    pub fn is_nil(&self) -> bool {
66        match *self {
67            Value::Nil => true,
68            _ => false,
69        }
70    }
71
72    pub fn bool(self) -> Result<bool, TypeError> {
73        use Value::*;
74        match self {
75            Boolean(b) => Ok(b),
76            v => Err(TypeError{desc: format!("{:?} does not contain a boolean value", v), v: v}),
77        }
78    }
79
80    pub fn int(self) -> Result<i64, TypeError> {
81        use Value::*;
82        match self {
83            Int8(i) => Ok(i as i64),
84            Int16(i) => Ok(i as i64),
85            Int32(i) => Ok(i as i64),
86            Int64(i) => Ok(i),
87            v => Err(TypeError{desc: format!("{:?} does not contain an int value", v), v: v}),
88        }
89    }
90
91    pub fn uint(self) -> Result<u64, TypeError> {
92        use Value::*;
93        match self {
94            Uint8(i) => Ok(i as u64),
95            Uint16(i) => Ok(i as u64),
96            Uint32(i) => Ok(i as u64),
97            Uint64(i) => Ok(i),
98            v => Err(TypeError{desc: format!("{:?} does not contain a uint value", v), v: v}),
99        }
100    }
101
102    pub fn float(self) -> Result<f64, TypeError> {
103        use Value::*;
104        match self {
105            Float32(f) => Ok(f as f64),
106            Float64(f) => Ok(f),
107            v => Err(TypeError{desc: format!("{:?} does not contain a float value", v), v: v}),
108        }
109    }
110
111    pub fn string(self) -> Result<string::String, TypeError> {
112        match self {
113            Value::String(s) => Ok(s),
114            v => Err(TypeError{desc: format!("{:?} does not contain a string value", v), v: v}),
115        }
116    }
117
118    pub fn binary(self) -> Result<Vec<u8>, TypeError> {
119        match self {
120            Value::Binary(data) => Ok(data),
121            v => Err(TypeError{desc: format!("{:?} does not contain a binary value", v), v: v}),
122        }
123    }
124
125    pub fn array(self) -> Result<Vec<Value>, TypeError> {
126        match self {
127            Value::Array(ar) => Ok(ar),
128            v => Err(TypeError{desc: format!("{:?} does not contain an array value", v), v: v}),
129        }
130    }
131
132    pub fn map(self) -> Result<ValueMap, TypeError> {
133        match self {
134            Value::Map(m) => Ok(m),
135            v => Err(TypeError{desc: format!("{:?} does not contain a map value", v), v: v}),
136        }
137    }
138
139    pub fn extended_type(&self) -> Option<i8> {
140        match *self {
141            Value::Extended(x, _) => Some(x),
142            _ => None,
143        }
144    }
145
146    pub fn extended_data(self) -> Option<Vec<u8>> {
147        match self {
148            Value::Extended(_, data) => Some(data),
149            _ => None,
150        }
151    }
152
153    pub fn extended<T>(self) -> Result<T, TypeError> {
154        use Value::*;
155        match self {
156            Extended(_, data) => Ok(unsafe { std::mem::transmute_copy(&data[0]) }),
157            v => Err(TypeError{desc: format!("{:?} does not contain an extended value", v), v: v})
158        }
159    }
160}
161
162#[derive(Clone, PartialEq, Debug)]
163pub struct ValueMap(pub Vec<(Value, Value)>);
164
165impl ValueMap {
166    /// Retrieve a value from the map.
167    pub fn get<T: IntoValue>(&self, key: T) -> Option<&Value> {
168        let key = key.into_value();
169        self.0.iter().find(|&&(ref k, _)| *k == key).map(|&(_, ref v)| v)
170    }
171
172    pub fn get_array<T: IntoValue>(&self, key: T) -> Option<Vec<Value>> {
173        self.get(key).map(|v| v.clone().array().unwrap())
174    }
175
176    pub fn get_bool<T: IntoValue>(&self, key: T) -> Option<bool> {
177        self.get(key).map(|v| v.clone().bool().unwrap())
178    }
179
180    pub fn get_string<T: IntoValue>(&self, key: T) -> Option<String> {
181        self.get(key).map(|v| v.clone().string().unwrap())
182    }
183
184    /// Returns the number of key/value pairs in the map.
185    pub fn len(&self) -> usize { self.0.len() }
186}
187
188/// A trait for types that can be written via MessagePack. This is mostly
189/// a convenience to avoid having to wrap them yourself each time.
190pub trait IntoValue {
191    fn into_value(self) -> Value;
192}
193
194impl IntoValue for () { fn into_value(self) -> Value { Value::Nil } }
195impl IntoValue for bool { fn into_value(self) -> Value { Value::Boolean(self) } }
196impl IntoValue for u8 { fn into_value(self) -> Value { Value::Uint8(self) } }
197impl IntoValue for u16 { fn into_value(self) -> Value { Value::Uint16(self) } }
198impl IntoValue for u32 { fn into_value(self) -> Value { Value::Uint32(self) } }
199impl IntoValue for u64 { fn into_value(self) -> Value { Value::Uint64(self) } }
200impl IntoValue for i8 { fn into_value(self) -> Value { Value::Int8(self) } }
201impl IntoValue for i16 { fn into_value(self) -> Value { Value::Int16(self) } }
202impl IntoValue for i32 { fn into_value(self) -> Value { Value::Int32(self) } }
203impl IntoValue for i64 { fn into_value(self) -> Value { Value::Int64(self) } }
204impl IntoValue for f32 { fn into_value(self) -> Value { Value::Float32(self) } }
205impl IntoValue for f64 { fn into_value(self) -> Value { Value::Float64(self) } }
206impl IntoValue for string::String { fn into_value(self) -> Value { Value::String(self) } }
207impl IntoValue for &'static str { fn into_value(self) -> Value { Value::String(String::from(self)) } }
208
209// TODO: re-enable this when we can specify that the implementation
210// for Vec<T> should *not* include u8
211/*
212impl IntoValue for Vec<u8> {
213    fn into_value(self) -> Value { Value::Binary(self) }
214}
215
216impl IntoValue for &'static [u8] {
217    fn into_value(self) -> Value {
218        let mut ar = Vec::with_capacity(self.len());
219        ar.push_all(self);
220        Value::Binary(ar)
221    }
222}
223*/
224
225impl<T: IntoValue> IntoValue for Vec<T> {
226    fn into_value(self) -> Value {
227        Value::Array(self.into_iter().map(|v| v.into_value()).collect())
228    }
229}
230
231// TODO: try and get this to work
232/*
233impl<T: IntoValue, V: IntoValue> IntoValue for std::collections::HashMap<T, V> {
234    fn into_value(self) -> Value {
235        Value::Map(self.into_iter().map(|(k, v)| (k.into_value(), v.pack())).collect())
236    }
237}
238*/
239
240/// Wraps a reader instance with a place to store the last byte that was read. This
241/// simulates pushing that byte back on to the reader if it wasn't recognized.
242pub struct Reader<R: Read + Send> {
243    next_byte: Option<u8>,
244    reader: R,
245}
246
247impl<R: Read + Send> Reader<R> {
248    pub fn new(reader: R) -> Reader<R> {
249        Reader{ next_byte: None, reader: reader }
250    }
251
252    pub fn read_value(&mut self) -> Result<Value, ReadError> {
253        use Value::*;
254
255        // Get the next byte, using the cached value if there is one.
256        let mut b = [0];
257        match self.next_byte {
258            Some(byte) => b[0] = byte,
259            None => if try!(self.reader.read(&mut b)) == 0 {
260                return Err(ReadError::NoData);
261            },
262        }
263
264        self.next_byte = None;
265
266        // Reads a big-endian integer from the provided reader. It's based on the implementation
267        // of std::old_io::Reader::read_be_uint_n, but ends up being slightly more efficient because
268        // it will store the result in the correctly-sized value rather than shove everything
269        // into a u64.
270        macro_rules! read_be_int(
271            ($src:expr, $int:ident, $s:expr) => ({
272                let mut val: $int = 0;
273                for (i, next) in $src.by_ref().take($s).bytes().enumerate() {
274                    val += (try!(next) as $int) << ($s - ((i + 1) as usize)) * 8;
275                }
276                val
277            })
278        );
279
280        // Reads a big-endian float from the provided reader. Floats are trickier because they need
281        // to be kept in raw-byte form and transmuted to the proper type, and there's no automatic
282        // way to determine the size of the data type, so that needs to be passed in manually.
283        macro_rules! read_be_float(
284            ($src:expr, $f:ident, $s:expr) => ({
285                let mut bytes: [u8; $s] = [0; $s];
286                for (i, next) in $src.by_ref().take($s).bytes().enumerate() {
287                    bytes[i] = try!(next);
288                }
289                if cfg!(target_endian = "little") {
290                    bytes.reverse();
291                }
292                unsafe { std::mem::transmute::<[u8; $s], $f>(bytes) }
293            });
294        );
295
296        // Reads an exact number of bytes from the provided reader.
297        macro_rules! read_exact(
298            ($src:expr, $n:expr) => ({
299                let mut v = Vec::with_capacity($n);
300                for next in $src.by_ref().take($n as u64).bytes() {
301                    v.push(try!(next));
302                }
303                v
304            })
305        );
306
307        match b[0] {
308            b @ byte::FIXINT_POS_RANGE_START...byte::FIXINT_POS_RANGE_END => Ok(Int8((b & 0b01111111) as i8)),
309
310            b @ byte::FIXMAP_RANGE_START...byte::FIXMAP_RANGE_END => {
311                let n = (b & 0b00001111) as usize;
312                let mut m = Vec::with_capacity(n);
313                for _ in 0..n {
314                    m.push((try!(self.read_value()), try!(self.read_value())));
315                }
316                Ok(Map(ValueMap(m)))
317            }
318
319            b @ byte::FIXARRAY_RANGE_START...byte::FIXARRAY_RANGE_END => {
320                let n = (b & 0b00001111) as usize;
321                let mut ar = Vec::with_capacity(n);
322                for _ in 0..n {
323                    ar.push(try!(self.read_value()));
324                }
325                Ok(Array(ar))
326            },
327
328            b @ byte::FIXSTR_RANGE_START...byte::FIXSTR_RANGE_END => {
329                let n = (b & 0b00011111) as usize;
330                match string::String::from_utf8(read_exact!(self.reader, n)) {
331                    Ok(s) => Ok(String(s)),
332                    Err(_) => panic!("received invalid utf-8"),
333                }
334            },
335
336            byte::NIL => Ok(Nil),
337
338            byte::FALSE => Ok(Boolean(false)),
339            byte::TRUE => Ok(Boolean(true)),
340
341            byte::U8 => Ok(Uint8(read_be_int!(self.reader, u8, 1))),
342            byte::U16 => Ok(Uint16(read_be_int!(self.reader, u16, 2))),
343            byte::U32 => Ok(Uint32(read_be_int!(self.reader, u32, 4))),
344            byte::U64 => Ok(Uint64(read_be_int!(self.reader, u64, 8))),
345
346            byte::I8 => Ok(Int8(read_be_int!(self.reader, i8, 1))),
347            byte::I16 => Ok(Int16(read_be_int!(self.reader, i16, 2))),
348            byte::I32 => Ok(Int32(read_be_int!(self.reader, i32, 4))),
349            byte::I64 => Ok(Int64(read_be_int!(self.reader, i64, 8))),
350
351            byte::F32 => Ok(Float32(read_be_float!(self.reader, f32, 4))),
352            byte::F64 => Ok(Float64(read_be_float!(self.reader, f64, 8))),
353
354            b if (b >> 5) == 0b00000101 => {
355                let n = (b & 0b00011111) as usize;
356                match string::String::from_utf8(read_exact!(self.reader, n)) {
357                    Ok(s) => Ok(String(s)),
358                    Err(_) => panic!("received invalid utf-8"),
359                }
360            },
361
362            byte::STR8 => {
363                let n = read_be_int!(self.reader, u8, 1) as usize;
364                match string::String::from_utf8(read_exact!(self.reader, n)) {
365                    Ok(s) => Ok(String(s)),
366                    Err(_) => panic!("received invalid utf-8"),
367                }
368            },
369
370            byte::STR16 => {
371                let n = read_be_int!(self.reader, u16, 2) as usize;
372                match string::String::from_utf8(read_exact!(self.reader, n)) {
373                    Ok(s) => Ok(String(s)),
374                    Err(_) => panic!("received invalid utf-8"),
375                }
376            },
377
378            byte::STR32 => {
379                let n = read_be_int!(self.reader, u32, 4) as usize;
380                match string::String::from_utf8(read_exact!(self.reader, n)) {
381                    Ok(s) => Ok(String(s)),
382                    Err(_) => panic!("received invalid utf-8"),
383                }
384            },
385
386            byte::BIN8 => {
387                let n = read_be_int!(self.reader, u8, 1) as usize;
388                Ok(Binary(read_exact!(self.reader, n)))
389            },
390
391            byte::BIN16 => {
392                let n = read_be_int!(self.reader, u16, 2) as usize;
393                Ok(Binary(read_exact!(self.reader, n)))
394            },
395
396            byte::BIN32 => {
397                let n = read_be_int!(self.reader, u32, 4) as usize;
398                Ok(Binary(read_exact!(self.reader, n)))
399            },
400
401            b if (b >> 4) == 0b00001001 => {
402                let n = (b & 0b00001111) as usize;
403                let mut ar = Vec::with_capacity(n);
404                for _ in 0..n {
405                    ar.push(try!(self.read_value()));
406                }
407                Ok(Array(ar))
408            },
409
410            byte::AR16 => {
411                let n = read_be_int!(self.reader, u16, 2) as usize;
412                let mut ar = Vec::with_capacity(n);
413                for _ in 0..n {
414                    ar.push(try!(self.read_value()));
415                }
416                Ok(Array(ar))
417            },
418
419            byte::AR32 => {
420                let n = read_be_int!(self.reader, u32, 4) as usize;
421                let mut ar = Vec::with_capacity(n);
422                for _ in 0..n {
423                    ar.push(try!(self.read_value()));
424                }
425                Ok(Array(ar))
426            },
427
428            b if (b >> 4) == 0b00001000 => {
429                let n = (b & 0b00001111) as usize;
430                let mut m = Vec::with_capacity(n);
431                for _ in 0..n {
432                    m.push((try!(self.read_value()), try!(self.read_value())));
433                }
434                Ok(Map(ValueMap(m)))
435            },
436
437            byte::MAP16 => {
438                let n = read_be_int!(self.reader, u16, 2) as usize;
439                let mut m = Vec::with_capacity(n);
440                for _ in 0..n {
441                    m.push((try!(self.read_value()), try!(self.read_value())));
442                }
443                Ok(Map(ValueMap(m)))
444            },
445
446            byte::MAP32 => {
447                let n = read_be_int!(self.reader, u32, 4) as usize;
448                let mut m = Vec::with_capacity(n);
449                for _ in 0..n {
450                    m.push((try!(self.read_value()), try!(self.read_value())));
451                }
452                Ok(Map(ValueMap(m)))
453            },
454
455            // Extension types.
456            byte::FIXEXT1 => Ok(Extended(read_be_int!(self.reader, i8, 1), read_exact!(self.reader, 1))),
457            byte::FIXEXT2 => Ok(Extended(read_be_int!(self.reader, i8, 1), read_exact!(self.reader, 2))),
458            byte::FIXEXT4 => Ok(Extended(read_be_int!(self.reader, i8, 1), read_exact!(self.reader, 4))),
459            byte::FIXEXT8 => Ok(Extended(read_be_int!(self.reader, i8, 1), read_exact!(self.reader, 8))),
460            byte::FIXEXT16 => Ok(Extended(read_be_int!(self.reader, i8, 1), read_exact!(self.reader, 16))),
461
462            byte::EXT8 => {
463                let n = read_be_int!(self.reader, u8, 1) as usize;
464                Ok(Extended(read_be_int!(self.reader, i8, 1), read_exact!(self.reader, n)))
465            },
466
467            byte::EXT16 => {
468                let n = read_be_int!(self.reader, u16, 2) as usize;
469                Ok(Extended(read_be_int!(self.reader, i8, 1), read_exact!(self.reader, n)))
470            },
471
472            byte::EXT32 => {
473                let n = read_be_int!(self.reader, u32, 4) as usize;
474                Ok(Extended(read_be_int!(self.reader, i8, 1), read_exact!(self.reader, n)))
475            },
476
477            b @ byte::FIXINT_NEG_RANGE_START...byte::FIXINT_NEG_RANGE_END => Ok(Int8((b & 0b00011111) as i8)),
478
479            b => {
480                self.next_byte = Some(b);
481                Err(ReadError::Unrecognized(b))
482            },
483        }
484    }
485}
486
487/// Convenience wrapper for `write_value()`.
488pub fn write<W: Write, V: IntoValue>(dest: &mut W, val: V) -> Result<(), WriteError> {
489    write_value(dest, val.into_value())
490}
491
492/// Write any value as an Extended type. On success, returns the number of bytes written.
493///
494/// The `val` parameter will be automatically converted to its byte representation.
495pub fn write_ext<W: Write, T>(dest: &mut W, id: i8, val: T) -> Result<usize, WriteError> {
496    let data: &[u8] = unsafe {
497        slice::from_raw_parts(&val as *const _ as *const u8, std::mem::size_of::<T>())
498    };
499    try!(write_value(dest, Value::Extended(id, data.to_vec())));
500    Ok(data.len())
501}
502
503/// Write a message in MessagePack format for the given value.
504pub fn write_value<W: Write>(dest: &mut W, val: Value) -> Result<(), WriteError> {
505    use Value::*;
506    use std::mem::transmute;
507
508    // Convert an integer to its big-endian byte representation.
509    macro_rules! be_int(
510        ($x:expr, $n:ident, $s:expr) => ({
511            unsafe { transmute::<_, [u8; $s]>(($x as $n).to_be()) }
512        })
513    );
514
515    // Convert a float to its big-endian byte representation.
516    macro_rules! be_float(
517        ($x:expr, $f:ident, $s:expr) => ({
518            let mut bytes = unsafe { transmute::<$f, [u8; $s]>($x) };
519            if cfg!(target_endian = "little") {
520                bytes.reverse();
521            }
522            bytes
523        })
524    );
525
526    // Create a slice out of a leading byte with any number of slices appended to it.
527    macro_rules! data(
528        ($b:expr; $($data:expr),+) => ({
529            let mut v = Vec::with_capacity({ let mut size = 1; $( size += $data.len(); )+ size });
530            v.push($b); $( v.extend_from_slice(&$data); )+ &v.into_boxed_slice()
531        })
532    );
533
534    match val {
535        Nil => try!(dest.write_all(&[byte::NIL])),
536
537        Boolean(false) => try!(dest.write_all(&[byte::FALSE])),
538        Boolean(true) => try!(dest.write_all(&[byte::TRUE])),
539
540        Uint8(x) => try!(dest.write_all(&[byte::U8, x])),
541        Uint16(x) => try!(dest.write_all(data![byte::U16; be_int!(x, u16, 2)])),
542        Uint32(x) => try!(dest.write_all(data![byte::U32; be_int!(x, u32, 4)])),
543        Uint64(x) => try!(dest.write_all(data![byte::U64; be_int!(x, u64, 8)])),
544
545        Int8(x) => try!(dest.write_all(&[byte::I8, x as u8])),
546        Int16(x) => try!(dest.write_all(data![byte::I16; be_int!(x, i16, 2)])),
547        Int32(x) => try!(dest.write_all(data![byte::I32; be_int!(x, i32, 4)])),
548        Int64(x) => try!(dest.write_all(data![byte::I64; be_int!(x, i64, 8)])),
549
550        Float32(x) => try!(dest.write_all(data![byte::F32; be_float!(x, f32, 4)])),
551        Float64(x) => try!(dest.write_all(data![byte::F64; be_float!(x, f64, 8)])),
552
553        String(s) => {
554            let bytes = s.as_bytes();
555            let n = bytes.len();
556            try!(match n {
557                0...31 => Ok(try!(dest.write_all(data![(0b10100000 | n) as u8; bytes]))), // fixstr
558                32...255 => Ok(try!(dest.write_all(data![byte::STR8; [n as u8], bytes]))), // str 8
559                256...65535 => Ok(try!(dest.write_all(data![byte::STR16; be_int!(n, u16, 2), bytes]))), // str 16
560                65536...4294967295 => Ok(try!(dest.write_all(data![byte::STR32; be_int!(n, u32, 4), bytes]))), // str 32
561                _ => Err(WriteError::TooMuchData(n)),
562            });
563        },
564
565        Binary(b) => {
566            let n = b.len();
567            try!(match n {
568                0...255 => Ok(try!(dest.write_all(data![byte::BIN8; be_int!(n, u8, 1), b.as_slice()]))), // bin 8
569                256...65535 => Ok(try!(dest.write_all(data![byte::BIN16; be_int!(n, u16, 2), b.as_slice()]))), // bin 16
570                65536...4294967295 => Ok(try!(dest.write_all(data![byte::BIN32; be_int!(n, u32, 4), b.as_slice()]))), // bin 32
571                _ => Err(WriteError::TooMuchData(n)),
572            });
573        },
574
575        Array(values) => {
576            let n = values.len();
577            try!(match n {
578                0...15 => Ok(try!(dest.write_all(&[(0b10010000 | n) as u8]))), // fixarray
579                16...65535 => Ok(try!(dest.write_all(data![byte::AR16; be_int!(n, u16, 2)]))), // 16 array
580                65536...4294967295 => Ok(try!(dest.write_all(data![byte::AR32; be_int!(n, u32, 4)]))), // 32 array
581                _ => Err(WriteError::TooMuchData(n)),
582            });
583            for v in values.into_iter() {
584                try!(write_value(dest, v));
585            }
586        },
587
588        Map(entries) => {
589            let n = entries.len();
590            try!(match n {
591                0...15 => Ok(try!(dest.write_all(&[(0b10000000 | n) as u8]))), // fixmap
592                16...65535 => Ok(try!(dest.write_all(data![byte::MAP16; be_int!(n, u16, 2)]))), // 16 map
593                65536...4294967295 => Ok(try!(dest.write_all(data![byte::MAP32; be_int!(n, u32, 4)]))), // 32 map
594                _ => Err(WriteError::TooMuchData(n)),
595            });
596            for (k, v) in entries.0.into_iter() {
597                try!(write_value(dest, k));
598                try!(write_value(dest, v));
599            }
600        },
601
602        Extended(id, data) => {
603            let n = data.len();
604            try!(match n {
605                1 => Ok(try!(dest.write_all(&[byte::FIXEXT1]))),
606                2 => Ok(try!(dest.write_all(&[byte::FIXEXT2]))),
607                4 => Ok(try!(dest.write_all(&[byte::FIXEXT4]))),
608                8 => Ok(try!(dest.write_all(&[byte::FIXEXT8]))),
609                16 => Ok(try!(dest.write_all(&[byte::FIXEXT16]))),
610                0...255 => Ok(try!(dest.write_all(&[byte::EXT8, n as u8]))), // ext 8
611                256...65535 => Ok(try!(dest.write_all(data![byte::MAP16; be_int!(n, u16, 2)]))), // ext 16
612                65536...4294967295 => Ok(try!(dest.write_all(data![byte::MAP32; be_int!(n, u32, 4)]))), // ext 32
613                _ => Err(WriteError::TooMuchData(n)),
614            });
615            try!(dest.write_all(&[id as u8]));
616            try!(dest.write_all(data.as_slice()));
617        },
618    }
619    Ok(())
620}
621
622/* -- Errors -- */
623
624#[derive(Debug)]
625pub struct TypeError {
626    v: Value,
627    desc: String,
628}
629
630impl TypeError {
631    /// Retrieve the value that caused the type error.
632    pub fn value(self) -> Value { self.v }
633}
634
635impl Error for TypeError {
636    fn description(&self) -> &str { self.desc.as_str() }
637    fn cause(&self) -> Option<&Error> { None }
638}
639
640impl std::fmt::Display for TypeError {
641    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
642        write!(fmt, "{}", self)
643    }
644}
645
646/// An error encountered while trying to write a value.
647#[derive(Debug)]
648pub enum WriteError {
649    Io(io::Error),
650    TooMuchData(usize),
651    UnregisteredExt(TypeId),
652}
653
654impl Error for WriteError {
655    fn description(&self) -> &str { "write error" }
656    fn cause(&self) -> Option<&Error> {
657        match *self {
658            WriteError::Io(ref e) => Some(e as &Error),
659            WriteError::TooMuchData(..) => None,
660            WriteError::UnregisteredExt(..) => None,
661        }
662    }
663}
664
665impl From<io::Error> for WriteError {
666    fn from(err: io::Error) -> WriteError {
667        WriteError::Io(err)
668    }
669}
670
671// For some reason the Error implementation barks if you don't do this.
672impl std::fmt::Display for WriteError {
673    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
674        write!(fmt, "{}", self)
675    }
676}
677
678/// An error encountered while trying to read a value.
679#[derive(Debug)]
680pub enum ReadError {
681    Io(io::Error),
682    NoData,
683    NotExtended,
684    Unrecognized(u8),
685}
686
687impl Error for ReadError {
688    fn description(&self) -> &str { "read error" }
689    fn cause(&self) -> Option<&Error> {
690        match *self {
691            ReadError::Io(ref e) => Some(e as &Error),
692            ReadError::NoData => None,
693            ReadError::NotExtended => None,
694            ReadError::Unrecognized(..) => None,
695        }
696    }
697}
698
699impl From<io::Error> for ReadError {
700    fn from(err: io::Error) -> ReadError {
701        ReadError::Io(err)
702    }
703}
704
705// For some reason the Error implementation barks if you don't do this.
706impl std::fmt::Display for ReadError {
707    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
708        write!(fmt, "{}", self)
709    }
710}
711
712#[cfg(test)]
713mod test {
714    extern crate rand;
715
716    use std::io::{self, Read, Write};
717    use std::mem;
718    use std::slice;
719    use std::string;
720    use std::sync::mpsc::{channel, Sender, Receiver};
721    use self::rand::{Rng, StdRng};
722    use super::{IntoValue, write_value};
723
724    pub struct ChanReader(pub Receiver<u8>);
725
726    impl Read for ChanReader {
727        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
728            for i in 0..buf.len() {
729                match self.0.recv() {
730                    Ok(byte) => buf[i] = byte,
731                    Err(..) => return Ok(i),
732                }
733            }
734            Ok(buf.len())
735        }
736    }
737
738    pub struct ChanWriter(pub Sender<u8>);
739
740    impl Write for ChanWriter {
741        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
742            if buf.len() == 0 {
743                Ok(0)
744            } else {
745                match self.0.send(buf[0]) {
746                    Ok(()) => Ok(1),
747                    Err(err) => Err(io::Error::new(io::ErrorKind::BrokenPipe, err)),
748                }
749            }
750        }
751
752        fn flush(&mut self) -> io::Result<()> {
753            Ok(())
754        }
755
756        fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
757            for byte in buf.iter() {
758                if let Err(err) = self.0.send(*byte) {
759                    return Err(io::Error::new(io::ErrorKind::BrokenPipe, err));
760                }
761            }
762            Ok(())
763        }
764    }
765
766    const LETTERS: &'static [char] = &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
767
768    fn test<T: IntoValue>(arg: T) {
769        let val = arg.into_value();
770        let (tx, rx) = channel();
771        write_value(&mut ChanWriter(tx), val.clone()).unwrap();
772        assert_eq!(super::Reader::new(&mut ChanReader(rx)).read_value().unwrap(), val);
773    }
774
775    fn random_string(n: usize) -> string::String {
776        let mut rng = StdRng::new().unwrap();
777
778        let mut s = string::String::with_capacity(n);
779        for _ in 0..n {
780            s.push(*rng.choose(LETTERS).unwrap());
781        }
782        s
783    }
784
785    #[test] fn test_nil() { test(()); }
786
787    #[test] fn test_u8() { test(3 as u8); }
788    #[test] fn test_u16() { test(36 as u16); }
789    #[test] fn test_u32() { test(360 as u32); }
790    #[test] fn test_u64() { test(3600 as u64); }
791    #[test] fn test_i8() { test(3 as i8); }
792    #[test] fn test_i16() { test(36 as i16); }
793    #[test] fn test_i32() { test(360 as i32); }
794    #[test] fn test_i64() { test(3600 as i64); }
795
796    #[test] fn test_f32() { test(1234.56 as f32); }
797    #[test] fn test_f64() { test(123456.78 as f64); }
798
799    #[test] fn write_tiny_string() { test(random_string(8)); }
800    #[test] fn write_short_string() { test(random_string(32)); }
801    #[test] fn write_medium_string() { test(random_string(256)); }
802
803    #[repr(packed)]
804    struct CustomStruct {
805        a: i8,
806        b: i16,
807    }
808
809    /// Note that extended values cannot include pointers to outside data.
810    #[test] fn test_extended() {
811        let (tx, rx) = channel();
812        let written = super::write_ext(&mut ChanWriter(tx), 13, CustomStruct{a: 13, b: 42}).unwrap();
813        assert_eq!(written, 3);
814
815        let value = super::Reader::new(&mut ChanReader(rx)).read_value().unwrap();
816        assert_eq!(value.extended_type().unwrap(), 13);
817
818        let x: CustomStruct = value.extended().unwrap();
819        assert_eq!(x.a, 13);
820        assert_eq!(x.b, 42);
821    }
822}