Skip to content

Encode/decode to/from references to readers #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 10, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 24 additions & 29 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -14,43 +20,32 @@ pub use reader::DecoderReader;
mod writer;
mod reader;

pub fn encode<T: Encodable<EncoderWriter<MemWriter>, IoError>>(t: &T) ->
Result<Vec<u8>, IoError> {
match encode_into(t, MemWriter::new()) {
Ok(w) => Ok(w.unwrap()),
Err((_, e)) => Err(e)
pub fn encode<'a, T: Encodable<EncoderWriter<'a, MemWriter>, IoError>>(t: &T) ->IoResult<Vec<u8>> {
let mut w = MemWriter::new();
match encode_into(t, &mut w) {
Ok(()) => Ok(w.unwrap()),
Err(e) => Err(e)
}
}

pub fn decode<T: Decodable<DecoderReader<MemReader>, IoError>>(b: Vec<u8>) ->
Result<T, (IoError, Vec<u8>)> {
match decode_from(MemReader::new(b)) {
Ok((t, _)) => Ok(t),
Err((e, r)) => Err((e, r.unwrap()))
}
pub fn decode<'a, T: Decodable<DecoderReader<'a, MemReader>, IoError>>(b: Vec<u8>) -> IoResult<T> {
decode_from(&mut MemReader::new(b))
}

pub fn encode_into<W: Writer, T: Encodable<EncoderWriter<W>, IoError>>
(t: &T, w: W)
-> Result<W, (W, IoError)> {
let mut writer = writer::EncoderWriter::new(w);
match t.encode(&mut writer) {
Ok(()) => Ok(writer.unwrap()),
Err(e) => Err((writer.unwrap(), e))
// 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<EncoderWriter<'a, W>, IoError>>(t: &T, w: &mut W) -> IoResult<()> {
unsafe {
t.encode(std::mem::transmute(&mut writer::EncoderWriter::new(w)))
}
}

// 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<R: Reader, T: Decodable<DecoderReader<R>, IoError>>(r: R) ->
Result<(T, R), (IoError, R)> {
let mut reader = reader::DecoderReader::new(r);
let x: Result<T, IoError> = 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<DecoderReader<'a, R>, IoError>>(r: &mut R) -> IoResult<T> {
unsafe {
Decodable::decode(std::mem::transmute(&mut reader::DecoderReader::new(r)))
}
}

Expand Down
96 changes: 46 additions & 50 deletions src/reader.rs
Original file line number Diff line number Diff line change
@@ -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<R> {
reader: BufferedReader<R>
pub struct DecoderReader<'a, R: 'a> {
reader: &'a mut R
}

impl <R: Reader> DecoderReader<R> {
pub fn new(r: R) -> DecoderReader<R> {
impl<'a, R: Reader+Buffer> DecoderReader<'a, R> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this R requiring Buffer?

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 <R: Reader> Decoder<IoError> for DecoderReader<R> {
fn read_nil(&mut self) -> Result<(), IoError> {
impl<'a, R: Reader+Buffer> Decoder<IoError> for DecoderReader<'a, R> {
fn read_nil(&mut self) -> IoResult<()> {
Ok(())
}
fn read_uint(&mut self) -> Result<uint, IoError> {
fn read_uint(&mut self) -> IoResult<uint> {
match self.reader.read_be_u64() {
Ok(x) => Ok(x as uint),
Err(e) => Err(e)
}
}
fn read_u64(&mut self) -> Result<u64, IoError> {
fn read_u64(&mut self) -> IoResult<u64> {
self.reader.read_be_u64()
}
fn read_u32(&mut self) -> Result<u32, IoError> {
fn read_u32(&mut self) -> IoResult<u32> {
self.reader.read_be_u32()
}
fn read_u16(&mut self) -> Result<u16, IoError> {
fn read_u16(&mut self) -> IoResult<u16> {
self.reader.read_be_u16()
}
fn read_u8(&mut self) -> Result<u8, IoError> {
fn read_u8(&mut self) -> IoResult<u8> {
self.reader.read_u8()
}
fn read_int(&mut self) -> Result<int, IoError> {
fn read_int(&mut self) -> IoResult<int> {
self.reader.read_be_int()
}
fn read_i64(&mut self) -> Result<i64, IoError> {
fn read_i64(&mut self) -> IoResult<i64> {
self.reader.read_be_i64()
}
fn read_i32(&mut self) -> Result<i32, IoError> {
fn read_i32(&mut self) -> IoResult<i32> {
self.reader.read_be_i32()
}
fn read_i16(&mut self) -> Result<i16, IoError> {
fn read_i16(&mut self) -> IoResult<i16> {
self.reader.read_be_i16()
}
fn read_i8(&mut self) -> Result<i8, IoError> {
fn read_i8(&mut self) -> IoResult<i8> {
self.reader.read_i8()
}
fn read_bool(&mut self) -> Result<bool, IoError> {
fn read_bool(&mut self) -> IoResult<bool> {
match try!(self.reader.read_i8()) {
1 => Ok(true),
_ => Ok(false)
}
}
fn read_f64(&mut self) -> Result<f64, IoError> {
fn read_f64(&mut self) -> IoResult<f64> {
self.reader.read_be_f64()
}
fn read_f32(&mut self) -> Result<f32, IoError> {
fn read_f32(&mut self) -> IoResult<f32> {
self.reader.read_be_f32()
}
fn read_char(&mut self) -> Result<char, IoError> {
fn read_char(&mut self) -> IoResult<char> {
self.reader.read_char()
}
fn read_str(&mut self) -> Result<String, IoError> {
fn read_str(&mut self) -> IoResult<String> {
let len = try!(self.read_uint());
let mut vector = Vec::with_capacity(len as uint);
for _ in range(0, len) {
Expand All @@ -82,83 +78,83 @@ impl <R: Reader> Decoder<IoError> for DecoderReader<R> {
Ok(String::from_utf8(vector).unwrap())
}
fn read_enum<T>(&mut self, _: &str,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
f(self)
}
fn read_enum_variant<T>(&mut self, _: &[&str],
f: |&mut DecoderReader<R>, uint| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>, uint| -> IoResult<T>) -> IoResult<T> {
let id = try!(self.read_uint());
f(self, id)
}
fn read_enum_variant_arg<T>(&mut self, _: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
f(self)
}
fn read_enum_struct_variant<T>(&mut self, names: &[&str],
f: |&mut DecoderReader<R>, uint| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>, uint| -> IoResult<T>) -> IoResult<T> {
self.read_enum_variant(names, f)
}
fn read_enum_struct_variant_field<T>(&mut self, _: &str, f_idx: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
self.read_enum_variant_arg(f_idx, f)
}
fn read_struct<T>(&mut self, _: &str, _: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
f(self)
}
fn read_struct_field<T>(&mut self, _: &str, _: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
f(self)
}
fn read_tuple<T>(&mut self,
f: |&mut DecoderReader<R>, uint| -> Result<T, IoError>) ->
Result<T, IoError> {
f: |&mut DecoderReader<'a, R>, uint| -> IoResult<T>) ->
IoResult<T> {
let len = try!(self.read_uint());
f(self, len)
}
fn read_tuple_arg<T>(&mut self, _: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
f(self)
}
fn read_tuple_struct<T>(&mut self, _: &str,
f: |&mut DecoderReader<R>, uint| -> Result<T, IoError>) ->
Result<T, IoError> {
f: |&mut DecoderReader<'a, R>, uint| -> IoResult<T>) ->
IoResult<T> {
self.read_tuple(f)
}
fn read_tuple_struct_arg<T>(&mut self, a_idx: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
self.read_tuple_arg(a_idx, f)
}
fn read_option<T>(&mut self,
f: |&mut DecoderReader<R>, bool| -> Result<T, IoError>) ->
Result<T, IoError> {
f: |&mut DecoderReader<'a, R>, bool| -> IoResult<T>) ->
IoResult<T> {
match try!(self.reader.read_u8()) {
1 => f(self, true),
_ => f(self, false)
}
}
fn read_seq<T>(&mut self,
f: |&mut DecoderReader<R>, uint| -> Result<T, IoError>) ->
Result<T, IoError> {
f: |&mut DecoderReader<'a, R>, uint| -> IoResult<T>) ->
IoResult<T> {
let len = try!(self.read_uint());
f(self, len)
}
fn read_seq_elt<T>(&mut self, _: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
f(self)
}
fn read_map<T>(&mut self,
f: |&mut DecoderReader<R>, uint| -> Result<T, IoError>) ->
Result<T, IoError> {
f: |&mut DecoderReader<'a, R>, uint| -> IoResult<T>) ->
IoResult<T> {
let len = try!(self.read_uint());
f(self, len)
}
fn read_map_elt_key<T>(&mut self, _: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
f(self)
}
fn read_map_elt_val<T>(&mut self, _: uint,
f: |&mut DecoderReader<R>| -> Result<T, IoError>) -> Result<T, IoError> {
f: |&mut DecoderReader<'a, R>| -> IoResult<T>) -> IoResult<T> {
f(self)
}
fn error(&mut self, err: &str) -> IoError {
Expand Down
6 changes: 3 additions & 3 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use super::DecoderReader;
use super::encode;
use super::decode;

fn the_same<
V: Encodable<EncoderWriter<MemWriter>, IoError> +
Decodable<DecoderReader<MemReader>, IoError> +
fn the_same<'a,
V: Encodable<EncoderWriter<'a, MemWriter>, IoError> +
Decodable<DecoderReader<'a, MemReader>, IoError> +
PartialEq + Show>(element: V) {
assert!(element == decode(encode(&element).unwrap()).unwrap());
}
Expand Down
Loading