diff --git a/src/lib.rs b/src/lib.rs index 8a076c9..0bc73bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,146 +1,12 @@ +#![feature(struct_variant)] + extern crate serialize; -use std::io::Writer; -use std::io::IoError; -use serialize::Encoder; +pub use writer::EncoderWriter; +pub use reader::DecoderReader; -type EwResult = Result<(), IoError>; +mod writer; +mod reader; -struct EncoderWriter { - writer: W -} - -impl EncoderWriter { - fn new(w: W) -> EncoderWriter { - EncoderWriter{ writer: w } - } - - fn unwrap(self) -> W { - self.writer - } -} - -impl Encoder for EncoderWriter { - fn emit_nil(&mut self) -> EwResult { Ok(()) } - fn emit_uint(&mut self, v: uint) -> EwResult { - Ok(()) - } - fn emit_u64(&mut self, v: u64) -> EwResult { - Ok(()) - } - fn emit_u32(&mut self, v: u32) -> EwResult { - Ok(()) - } - fn emit_u16(&mut self, v: u16) -> EwResult { - Ok(()) - } - fn emit_u8(&mut self, v: u8) -> EwResult { - Ok(()) - } - fn emit_int(&mut self, v: int) -> EwResult { - Ok(()) - } - fn emit_i64(&mut self, v: i64) -> EwResult { - Ok(()) - } - fn emit_i32(&mut self, v: i32) -> EwResult { - Ok(()) - } - fn emit_i16(&mut self, v: i16) -> EwResult { - Ok(()) - } - fn emit_i8(&mut self, v: i8) -> EwResult { - Ok(()) - } - fn emit_bool(&mut self, v: bool) -> EwResult { - Ok(()) - } - fn emit_f64(&mut self, v: f64) -> EwResult { - Ok(()) - } - fn emit_f32(&mut self, v: f32) -> EwResult { - Ok(()) - } - fn emit_char(&mut self, v: char) -> EwResult { - Ok(()) - } - fn emit_str(&mut self, v: &str) -> EwResult { - Ok(()) - } - fn emit_enum(&mut self, name: &str, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_enum_variant(&mut self, - v_name: &str, v_id: uint, len: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_enum_variant_arg(&mut self, a_idx: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_enum_struct_variant(&mut self, v_name: &str, v_id: uint, - len: uint, f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_enum_struct_variant_field(&mut self, f_name: &str, - f_idx: uint, f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_struct(&mut self, name: &str, len: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_struct_field(&mut self, f_name: &str, f_idx: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_tuple(&mut self, len: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_tuple_arg(&mut self, idx: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_tuple_struct(&mut self, name: &str, len: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_tuple_struct_arg(&mut self, f_idx: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_option(&mut self, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_option_none(&mut self) -> EwResult { - Ok(()) - } - fn emit_option_some(&mut self, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_seq(&mut self, len: uint, - f: |this: &mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_seq_elt(&mut self, idx: uint, - f: |this: &mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_map(&mut self, len: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_map_elt_key(&mut self, idx: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } - fn emit_map_elt_val(&mut self, idx: uint, - f: |&mut EncoderWriter| -> EwResult) -> EwResult { - Ok(()) - } -} +#[cfg(test)] +mod test; diff --git a/src/reader.rs b/src/reader.rs new file mode 100644 index 0000000..1141a03 --- /dev/null +++ b/src/reader.rs @@ -0,0 +1,147 @@ +use std::io::Reader; +use std::io::BufferedReader; +use std::io::IoError; +use std::io::OtherIoError; +use serialize::Decoder; + +type EwResult = Result<(), IoError>; + +pub struct DecoderReader { + reader: BufferedReader +} + +impl DecoderReader { + pub fn new(r: R) -> DecoderReader { + DecoderReader{ reader: BufferedReader::new(r) } + } + + pub fn unwrap(self) -> R { + self.reader.unwrap() + } +} + +impl Decoder for DecoderReader { + fn read_nil(&mut self) -> Result<(), IoError> { + Ok(()) + } + fn read_uint(&mut self) -> Result { + self.reader.read_be_uint() + } + fn read_u64(&mut self) -> Result { + self.reader.read_be_u64() + } + fn read_u32(&mut self) -> Result { + self.reader.read_be_u32() + } + fn read_u16(&mut self) -> Result { + self.reader.read_be_u16() + } + fn read_u8(&mut self) -> Result { + self.reader.read_u8() + } + fn read_int(&mut self) -> Result { + self.reader.read_be_int() + } + fn read_i64(&mut self) -> Result { + self.reader.read_be_i64() + } + fn read_i32(&mut self) -> Result { + self.reader.read_be_i32() + } + fn read_i16(&mut self) -> Result { + self.reader.read_be_i16() + } + fn read_i8(&mut self) -> Result { + self.reader.read_i8() + } + fn read_bool(&mut self) -> Result { + match try!(self.reader.read_i8()) { + 1 => Ok(true), + _ => Ok(false) + } + } + fn read_f64(&mut self) -> Result { + self.reader.read_be_f64() + } + fn read_f32(&mut self) -> Result { + self.reader.read_be_f32() + } + fn read_char(&mut self) -> Result { + self.reader.read_char() + } + fn read_str(&mut self) -> Result { + let len = try!(self.reader.read_be_uint()); + let mut string = String::new(); + for _ in range(0, len) { + string.push_char(try!(self.reader.read_char())); + } + Ok(string) + } + fn read_enum(&mut self, name: &str, f: |&mut DecoderReader| -> Result) -> Result { + f(self) + } + fn read_enum_variant(&mut self, names: &[&str], f: |&mut DecoderReader, uint| -> Result) -> Result { + let id = try!(self.reader.read_be_uint()); + //let len = try!(self.reader.read_be_uint()); + f(self, id) + } + fn read_enum_variant_arg(&mut self, a_idx: uint, f: |&mut DecoderReader| -> Result) -> Result { + let idx = try!(self.reader.read_be_uint()); + f(self) + } + fn read_enum_struct_variant(&mut self, names: &[&str], f: |&mut DecoderReader, uint| -> Result) -> Result { + self.read_enum_variant(names, f) + } + fn read_enum_struct_variant_field(&mut self, f_name: &str, f_idx: uint, f: |&mut DecoderReader| -> Result) -> Result { + self.read_enum_variant_arg(f_idx, f) + } + fn read_struct(&mut self, s_name: &str, len: uint, f: |&mut DecoderReader| -> Result) -> Result { + f(self) + } + fn read_struct_field(&mut self, f_name: &str, f_idx: uint, f: |&mut DecoderReader| -> Result) -> Result { + f(self) + } + fn read_tuple(&mut self, f: |&mut DecoderReader, uint| -> Result) -> Result { + let len = try!(self.reader.read_be_uint()); + f(self, len) + } + fn read_tuple_arg(&mut self, a_idx: uint, f: |&mut DecoderReader| -> Result) -> Result { + f(self) + } + fn read_tuple_struct(&mut self, s_name: &str, f: |&mut DecoderReader, uint| -> Result) -> Result { + self.read_tuple(f) + } + fn read_tuple_struct_arg(&mut self, a_idx: uint, f: |&mut DecoderReader| -> Result) -> Result { + self.read_tuple_arg(a_idx, f) + } + fn read_option(&mut self, f: |&mut DecoderReader, bool| -> Result) -> Result { + match try!(self.reader.read_u8()) { + 1 => f(self, true), + _ => f(self, false) + } + } + fn read_seq(&mut self, f: |&mut DecoderReader, uint| -> Result) -> Result { + let len = try!(self.reader.read_be_uint()); + f(self, len) + } + fn read_seq_elt(&mut self, idx: uint, f: |&mut DecoderReader| -> Result) -> Result { + f(self) + } + fn read_map(&mut self, f: |&mut DecoderReader, uint| -> Result) -> Result { + let len = try!(self.reader.read_be_uint()); + f(self, len) + } + fn read_map_elt_key(&mut self, idx: uint, f: |&mut DecoderReader| -> Result) -> Result { + f(self) + } + fn read_map_elt_val(&mut self, idx: uint, f: |&mut DecoderReader| -> Result) -> Result { + f(self) + } + fn error(&mut self, err: &str) -> IoError { + IoError { + kind: OtherIoError, + desc: "failure decoding or something, I don't know", + detail: Some(err.to_string()) + } + } +} diff --git a/src/test.rs b/src/test.rs new file mode 100644 index 0000000..cbc50d8 --- /dev/null +++ b/src/test.rs @@ -0,0 +1,169 @@ +use std::io::MemWriter; +use std::fmt::Show; +use std::io::MemReader; +use std::io::IoError; +use std::collections::hashmap::HashMap; + +use serialize::{ + Encoder, + Decoder, + Encodable, + Decodable +}; + +use super::EncoderWriter; +use super::DecoderReader; + +fn the_same< + V: Encodable, IoError> + + Decodable, IoError> + + PartialEq + Show>(element: V) { + let mem_w = MemWriter::new(); + let mut writer = EncoderWriter::new(mem_w); + element.encode(&mut writer); + + let bytes = writer.unwrap().unwrap(); + let mem_r = MemReader::new(bytes); + let mut reader = DecoderReader::new(mem_r); + + let decoded = Decodable::decode(&mut reader).unwrap(); + println!("{}, -> {}", element, decoded); + assert!(element == decoded); +} + +#[test] +fn test_numbers() { + // unsigned positive + the_same(5u8); + the_same(5u16); + the_same(5u32); + the_same(5u64); + // signed positive + the_same(5i8); + the_same(5i16); + the_same(5i32); + the_same(5i64); + // signed negative + the_same(-5i8); + the_same(-5i16); + the_same(-5i32); + the_same(-5i64); + // floating + the_same(-100f32); + the_same(0f32); + the_same(5f32); + the_same(-100f64); + the_same(5f64); +} + +#[test] +fn test_string() { + the_same("".to_string()); + the_same("a".to_string()); +} + +#[test] +fn test_tuple() { + the_same((1i,)); + the_same((1i,2i,3i)); + the_same((1i,"foo".to_string(),())); +} + +#[test] +fn test_basic_struct() { + #[deriving(Encodable, Decodable, PartialEq, Show)] + struct Easy { + x: int, + s: String, + y: uint + } + the_same(Easy{x: -4, s: "foo".to_string(), y: 10}); +} + +#[test] +fn test_nested_struct() { + #[deriving(Encodable, Decodable, PartialEq, Show)] + struct Easy { + x: int, + s: String, + y: uint + } + #[deriving(Encodable, Decodable, PartialEq, Show)] + struct Nest { + f: Easy, + b: uint, + s: Easy + } + + the_same(Nest { + f: Easy {x: -1, s: "foo".to_string(), y: 20}, + b: 100, + s: Easy {x: -100, s: "bar".to_string(), y: 20} + }); +} + +#[test] +fn test_struct_tuple() { + #[deriving(Encodable, Decodable, PartialEq, Show)] + struct TubStr(uint, String, f32); + + the_same(TubStr(5, "hello".to_string(), 3.2)); +} + +#[test] +fn option() { + the_same(Some(5u)); + the_same(Some("foo bar".to_string())); + the_same(None::); +} + +#[test] +fn enm() { + #[deriving(Encodable, Decodable, PartialEq, Show)] + enum TestEnum { + NoArg, + OneArg(uint), + AnotherNoArg + } + the_same(NoArg); + the_same(OneArg(4)); + the_same(AnotherNoArg); +} + + +#[test] +fn struct_enum() { + #[deriving(Encodable, Decodable, PartialEq, Show)] + enum TestEnum { + NoArg, + OneArg(uint), + AnotherNoArg, + StructLike{x: uint, y: f32} + } + the_same(NoArg); + the_same(OneArg(4)); + the_same(AnotherNoArg); + the_same(StructLike{x: 4, y: 3.14159}); +} + +#[test] +fn many() { + let v: Vec = vec![]; + the_same(v); + the_same(vec![1u]); + the_same(vec![1u,2,3,4,5,6]); +} + +#[test] +fn map(){ + let mut m = HashMap::new(); + m.insert(4u, "foo".to_string()); + m.insert(0u, "bar".to_string()); + the_same(m); +} + +#[test] +fn boole(){ + the_same(true); + the_same(false); +} diff --git a/src/writer.rs b/src/writer.rs new file mode 100644 index 0000000..ad99dfa --- /dev/null +++ b/src/writer.rs @@ -0,0 +1,156 @@ +use std::io::Writer; +use std::io::IoError; +use serialize::Encoder; + +type EwResult = Result<(), IoError>; + +pub struct EncoderWriter { + writer: W +} + +impl EncoderWriter { + pub fn new(w: W) -> EncoderWriter { + EncoderWriter{ writer: w } + } + + pub fn unwrap(self) -> W { + self.writer + } +} + +impl Encoder for EncoderWriter { + fn emit_nil(&mut self) -> EwResult { Ok(()) } + fn emit_uint(&mut self, v: uint) -> EwResult { + self.writer.write_be_uint(v) + } + fn emit_u64(&mut self, v: u64) -> EwResult { + self.writer.write_be_u64(v) + } + fn emit_u32(&mut self, v: u32) -> EwResult { + self.writer.write_be_u32(v) + } + fn emit_u16(&mut self, v: u16) -> EwResult { + self.writer.write_be_u16(v) + } + fn emit_u8(&mut self, v: u8) -> EwResult { + self.writer.write_u8(v) + } + fn emit_int(&mut self, v: int) -> EwResult { + self.writer.write_be_int(v) + } + fn emit_i64(&mut self, v: i64) -> EwResult { + self.writer.write_be_i64(v) + } + fn emit_i32(&mut self, v: i32) -> EwResult { + self.writer.write_be_i32(v) + } + fn emit_i16(&mut self, v: i16) -> EwResult { + self.writer.write_be_i16(v) + } + fn emit_i8(&mut self, v: i8) -> EwResult { + self.writer.write_i8(v) + } + fn emit_bool(&mut self, v: bool) -> EwResult { + self.writer.write_u8(if v {1} else {0}) + } + fn emit_f64(&mut self, v: f64) -> EwResult { + self.writer.write_be_f64(v) + } + fn emit_f32(&mut self, v: f32) -> EwResult { + self.writer.write_be_f32(v) + } + fn emit_char(&mut self, v: char) -> EwResult { + self.writer.write_char(v) + } + fn emit_str(&mut self, v: &str) -> EwResult { + try!(self.writer.write_be_uint(v.len())); + self.writer.write_str(v) + } + fn emit_enum(&mut self, name: &str, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f(self) + } + fn emit_enum_variant(&mut self, + v_name: &str, v_id: uint, len: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + try!(self.writer.write_be_uint(v_id)); + //try!(self.writer.write_be_uint(len)); + f(self) + } + fn emit_enum_variant_arg(&mut self, a_idx: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + try!(self.writer.write_be_uint(a_idx)); + f(self) + } + fn emit_enum_struct_variant(&mut self, v_name: &str, v_id: uint, + len: uint, f: |&mut EncoderWriter| -> EwResult) -> EwResult { + try!(self.writer.write_be_uint(v_id)); + try!(self.writer.write_str(v_name)); + f(self) + } + fn emit_enum_struct_variant_field(&mut self, f_name: &str, + f_idx: uint, f: |&mut EncoderWriter| -> EwResult) -> EwResult { + try!(self.writer.write_be_uint(f_idx)); + try!(self.writer.write_str(f_name)); + f(self) + } + fn emit_struct(&mut self, name: &str, len: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f(self) + } + fn emit_struct_field(&mut self, f_name: &str, f_idx: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f(self) + } + fn emit_tuple(&mut self, len: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + try!(self.writer.write_be_uint(len)); + f(self) + } + fn emit_tuple_arg(&mut self, idx: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f(self) + } + fn emit_tuple_struct(&mut self, name: &str, len: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + self.emit_tuple(len, f) + } + fn emit_tuple_struct_arg(&mut self, f_idx: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + self.emit_tuple_arg(f_idx, f) + } + fn emit_option(&mut self, + f: |&mut EncoderWriter| -> 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 { + try!(self.writer.write_u8(1)); + f(self) + } + fn emit_seq(&mut self, len: uint, + f: |this: &mut EncoderWriter| -> EwResult) -> EwResult { + try!(self.writer.write_be_uint(len)); + f(self) + } + fn emit_seq_elt(&mut self, idx: uint, + f: |this: &mut EncoderWriter| -> EwResult) -> EwResult { + f(self) + } + fn emit_map(&mut self, len: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + try!(self.writer.write_be_uint(len)); + f(self) + } + fn emit_map_elt_key(&mut self, idx: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f(self) + } + fn emit_map_elt_val(&mut self, idx: uint, + f: |&mut EncoderWriter| -> EwResult) -> EwResult { + f(self) + } +}