diff --git a/src/lib.rs b/src/lib.rs index 63618ae..d48aaa1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,16 @@ +#![crate_name = "binary_encode"] +#![crate_type = "rlib"] +#![crate_type = "dylib"] + #![feature(struct_variant)] extern crate serialize; +use std::io::Buffer; use std::io::MemWriter; use std::io::MemReader; use std::io::IoError; +use std::io::IoResult; use serialize::Encodable; use serialize::Decodable; @@ -14,43 +20,32 @@ pub use reader::DecoderReader; mod writer; mod reader; -pub fn encode, IoError>>(t: &T) -> -Result, IoError> { - match encode_into(t, MemWriter::new()) { - Ok(w) => Ok(w.unwrap()), - Err((_, e)) => Err(e) +pub fn encode<'a, T: Encodable, IoError>>(t: &T) ->IoResult> { + let mut w = MemWriter::new(); + match encode_into(t, &mut w) { + Ok(()) => Ok(w.unwrap()), + Err(e) => Err(e) } } -pub fn decode, IoError>>(b: Vec) -> -Result)> { - match decode_from(MemReader::new(b)) { - Ok((t, _)) => Ok(t), - Err((e, r)) => Err((e, r.unwrap())) +pub fn decode<'a, T: Decodable, IoError>>(b: Vec) -> IoResult { + decode_from(&mut MemReader::new(b)) +} + +// In order to be able to pass MemReaders/MemWriters by reference, I borrowed the method used in +// the current json encoder in the stdlib + +// TODO: Make code safe https://github.com/rust-lang/rust/issues/14302 +pub fn encode_into<'a, W: 'a+Writer, T: Encodable, IoError>>(t: &T, w: &mut W) -> IoResult<()> { + unsafe { + t.encode(std::mem::transmute(&mut writer::EncoderWriter::new(w))) } } -pub fn encode_into, IoError>> -(t: &T, w: W) --> Result { - let mut writer = writer::EncoderWriter::new(w); - match t.encode(&mut writer) { - Ok(()) => Ok(writer.unwrap()), - Err(e) => Err((writer.unwrap(), e)) - } -} - -// TODO: When higher order lifetimes land, make this so that the -// reader is passed in by &mut instead of by ownership. -pub fn decode_from, IoError>>(r: R) -> -Result<(T, R), (IoError, R)> { - let mut reader = reader::DecoderReader::new(r); - let x: Result = Decodable::decode(&mut reader); - let mem = reader.unwrap(); - - match x { - Ok(t) => Ok((t, mem)), - Err(e) => Err((e, mem)) +// TODO: Make code safe https://github.com/rust-lang/rust/issues/14302 +pub fn decode_from<'a, R: 'a+Reader+Buffer, T: Decodable, IoError>>(r: &mut R) -> IoResult { + unsafe { + Decodable::decode(std::mem::transmute(&mut reader::DecoderReader::new(r))) } } diff --git a/src/reader.rs b/src/reader.rs index 38b18ab..1525f9d 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -1,79 +1,75 @@ +use std::io::Buffer; use std::io::Reader; -use std::io::BufferedReader; use std::io::IoError; +use std::io::IoResult; use std::io::OtherIoError; use serialize::Decoder; -type EwResult = Result<(), IoError>; - -pub struct DecoderReader { - reader: BufferedReader +pub struct DecoderReader<'a, R: 'a> { + reader: &'a mut R } -impl DecoderReader { - pub fn new(r: R) -> DecoderReader { +impl<'a, R: Reader+Buffer> DecoderReader<'a, R> { + pub fn new(r: &'a mut R) -> DecoderReader<'a, R> { DecoderReader { - reader: BufferedReader::new(r) + reader: r } } - pub fn unwrap(self) -> R { - self.reader.unwrap() - } } -impl Decoder for DecoderReader { - fn read_nil(&mut self) -> Result<(), IoError> { +impl<'a, R: Reader+Buffer> Decoder for DecoderReader<'a, R> { + fn read_nil(&mut self) -> IoResult<()> { Ok(()) } - fn read_uint(&mut self) -> Result { + fn read_uint(&mut self) -> IoResult { match self.reader.read_be_u64() { Ok(x) => Ok(x as uint), Err(e) => Err(e) } } - fn read_u64(&mut self) -> Result { + fn read_u64(&mut self) -> IoResult { self.reader.read_be_u64() } - fn read_u32(&mut self) -> Result { + fn read_u32(&mut self) -> IoResult { self.reader.read_be_u32() } - fn read_u16(&mut self) -> Result { + fn read_u16(&mut self) -> IoResult { self.reader.read_be_u16() } - fn read_u8(&mut self) -> Result { + fn read_u8(&mut self) -> IoResult { self.reader.read_u8() } - fn read_int(&mut self) -> Result { + fn read_int(&mut self) -> IoResult { self.reader.read_be_int() } - fn read_i64(&mut self) -> Result { + fn read_i64(&mut self) -> IoResult { self.reader.read_be_i64() } - fn read_i32(&mut self) -> Result { + fn read_i32(&mut self) -> IoResult { self.reader.read_be_i32() } - fn read_i16(&mut self) -> Result { + fn read_i16(&mut self) -> IoResult { self.reader.read_be_i16() } - fn read_i8(&mut self) -> Result { + fn read_i8(&mut self) -> IoResult { self.reader.read_i8() } - fn read_bool(&mut self) -> Result { + fn read_bool(&mut self) -> IoResult { match try!(self.reader.read_i8()) { 1 => Ok(true), _ => Ok(false) } } - fn read_f64(&mut self) -> Result { + fn read_f64(&mut self) -> IoResult { self.reader.read_be_f64() } - fn read_f32(&mut self) -> Result { + fn read_f32(&mut self) -> IoResult { self.reader.read_be_f32() } - fn read_char(&mut self) -> Result { + fn read_char(&mut self) -> IoResult { self.reader.read_char() } - fn read_str(&mut self) -> Result { + fn read_str(&mut self) -> IoResult { let len = try!(self.read_uint()); let mut vector = Vec::with_capacity(len as uint); for _ in range(0, len) { @@ -82,83 +78,83 @@ impl Decoder for DecoderReader { Ok(String::from_utf8(vector).unwrap()) } fn read_enum(&mut self, _: &str, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { f(self) } fn read_enum_variant(&mut self, _: &[&str], - f: |&mut DecoderReader, uint| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>, uint| -> IoResult) -> IoResult { let id = try!(self.read_uint()); f(self, id) } fn read_enum_variant_arg(&mut self, _: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { f(self) } fn read_enum_struct_variant(&mut self, names: &[&str], - f: |&mut DecoderReader, uint| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>, uint| -> IoResult) -> IoResult { self.read_enum_variant(names, f) } fn read_enum_struct_variant_field(&mut self, _: &str, f_idx: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { self.read_enum_variant_arg(f_idx, f) } fn read_struct(&mut self, _: &str, _: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { f(self) } fn read_struct_field(&mut self, _: &str, _: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { f(self) } fn read_tuple(&mut self, - f: |&mut DecoderReader, uint| -> Result) -> - Result { + f: |&mut DecoderReader<'a, R>, uint| -> IoResult) -> + IoResult { let len = try!(self.read_uint()); f(self, len) } fn read_tuple_arg(&mut self, _: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { f(self) } fn read_tuple_struct(&mut self, _: &str, - f: |&mut DecoderReader, uint| -> Result) -> - Result { + f: |&mut DecoderReader<'a, R>, uint| -> IoResult) -> + IoResult { self.read_tuple(f) } fn read_tuple_struct_arg(&mut self, a_idx: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { self.read_tuple_arg(a_idx, f) } fn read_option(&mut self, - f: |&mut DecoderReader, bool| -> Result) -> - Result { + f: |&mut DecoderReader<'a, R>, bool| -> IoResult) -> + IoResult { match try!(self.reader.read_u8()) { 1 => f(self, true), _ => f(self, false) } } fn read_seq(&mut self, - f: |&mut DecoderReader, uint| -> Result) -> - Result { + f: |&mut DecoderReader<'a, R>, uint| -> IoResult) -> + IoResult { let len = try!(self.read_uint()); f(self, len) } fn read_seq_elt(&mut self, _: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { f(self) } fn read_map(&mut self, - f: |&mut DecoderReader, uint| -> Result) -> - Result { + f: |&mut DecoderReader<'a, R>, uint| -> IoResult) -> + IoResult { let len = try!(self.read_uint()); f(self, len) } fn read_map_elt_key(&mut self, _: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { f(self) } fn read_map_elt_val(&mut self, _: uint, - f: |&mut DecoderReader| -> Result) -> Result { + f: |&mut DecoderReader<'a, R>| -> IoResult) -> IoResult { f(self) } fn error(&mut self, err: &str) -> IoError { diff --git a/src/test.rs b/src/test.rs index aebaed3..ecce570 100644 --- a/src/test.rs +++ b/src/test.rs @@ -16,9 +16,9 @@ use super::DecoderReader; use super::encode; use super::decode; -fn the_same< - V: Encodable, IoError> + - Decodable, IoError> + +fn the_same<'a, + V: Encodable, IoError> + + Decodable, IoError> + PartialEq + Show>(element: V) { assert!(element == decode(encode(&element).unwrap()).unwrap()); } diff --git a/src/writer.rs b/src/writer.rs index 16a2ff3..edf16b5 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -1,24 +1,21 @@ use std::io::Writer; use std::io::IoError; +use std::io::IoResult; use serialize::Encoder; -type EwResult = Result<(), IoError>; +type EwResult = IoResult<()>; -pub struct EncoderWriter { - writer: W +pub struct EncoderWriter<'a, W: 'a> { + writer: &'a mut W } -impl EncoderWriter { - pub fn new(w: W) -> EncoderWriter { +impl <'a, W: Writer> EncoderWriter<'a, W> { + pub fn new(w: &'a mut W) -> EncoderWriter<'a, W> { EncoderWriter{ writer: w } } - - pub fn unwrap(self) -> W { - self.writer - } } -impl Encoder for EncoderWriter { +impl<'a, W: Writer> Encoder for EncoderWriter<'a, W> { fn emit_nil(&mut self) -> EwResult { Ok(()) } fn emit_uint(&mut self, v: uint) -> EwResult { self.writer.write_be_u64(v as u64) @@ -67,84 +64,84 @@ impl Encoder for EncoderWriter { self.writer.write_str(v) } fn emit_enum(&mut self, _: &str, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_enum_variant(&mut self, _: &str, v_id: uint, _: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { try!(self.emit_uint(v_id)); f(self) } fn emit_enum_variant_arg(&mut self, _: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_enum_struct_variant(&mut self, _: &str, _: uint, - _: uint, f: |&mut EncoderWriter| -> EwResult) -> EwResult { + _: uint, f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_enum_struct_variant_field(&mut self, _: &str, - _: uint, f: |&mut EncoderWriter| -> EwResult) -> EwResult { + _: uint, f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_struct(&mut self, _: &str, _: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_struct_field(&mut self, _: &str, _: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_tuple(&mut self, len: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { try!(self.emit_uint(len)); f(self) } fn emit_tuple_arg(&mut self, _: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_tuple_struct(&mut self, _: &str, len: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { self.emit_tuple(len, f) } fn emit_tuple_struct_arg(&mut self, f_idx: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { self.emit_tuple_arg(f_idx, f) } fn emit_option(&mut self, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_option_none(&mut self) -> EwResult { self.writer.write_u8(0) } fn emit_option_some(&mut self, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { try!(self.writer.write_u8(1)); f(self) } fn emit_seq(&mut self, len: uint, - f: |this: &mut EncoderWriter| -> EwResult) -> EwResult { + f: |this: &mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { try!(self.emit_uint(len)); f(self) } fn emit_seq_elt(&mut self, _: uint, - f: |this: &mut EncoderWriter| -> EwResult) -> EwResult { + f: |this: &mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_map(&mut self, len: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { try!(self.emit_uint(len)); f(self) } fn emit_map_elt_key(&mut self, _: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } fn emit_map_elt_val(&mut self, _: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f: |&mut EncoderWriter<'a, W>| -> EwResult) -> EwResult { f(self) } }