From a9c6061c9a542a617020073d0a6b187849d0e348 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sat, 29 Mar 2014 01:05:46 +0100 Subject: [PATCH] Register new snapshot --- src/librustc/driver/driver.rs | 15 +- src/librustc/metadata/decoder.rs | 17 +- src/librustc/metadata/encoder.rs | 5 - src/librustc/middle/astencode.rs | 312 ++- src/librustdoc/lib.rs | 15 +- src/libserialize/collection_impls_old.rs | 292 --- src/libserialize/ebml_old.rs | 1120 ---------- src/libserialize/json_old.rs | 2606 ---------------------- src/libserialize/lib.rs | 21 - src/libserialize/serialize_old.rs | 688 ------ src/libstd/cmp.rs | 10 - src/libstd/kinds.rs | 17 - src/libsyntax/ast.rs | 36 - src/libsyntax/codemap.rs | 18 - src/libsyntax/owned_slice.rs | 17 - src/libsyntax/parse/mod.rs | 10 - src/libsyntax/parse/token.rs | 17 - src/libtest/lib.rs | 22 +- src/libuuid/lib.rs | 32 +- src/snapshots.txt | 8 + 20 files changed, 153 insertions(+), 5125 deletions(-) delete mode 100644 src/libserialize/collection_impls_old.rs delete mode 100644 src/libserialize/ebml_old.rs delete mode 100644 src/libserialize/json_old.rs delete mode 100644 src/libserialize/serialize_old.rs diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 610764f17ad..7e7ccb8a1c6 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -168,17 +168,6 @@ fn filestem(&self) -> ~str { } } -// FIXME: remove unwrap_ after snapshot -#[cfg(stage0)] -fn unwrap_(t: T) -> T { - t -} - -#[cfg(not(stage0))] -fn unwrap_(r: Result) -> T { - r.unwrap() -} - pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input) -> ast::Crate { @@ -200,7 +189,7 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input) let mut stdout = io::BufferedWriter::new(io::stdout()); let mut json = json::PrettyEncoder::new(&mut stdout); // unwrapping so IoError isn't ignored - unwrap_(krate.encode(&mut json)); + krate.encode(&mut json).unwrap(); } if sess.show_span() { @@ -276,7 +265,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, let mut stdout = io::BufferedWriter::new(io::stdout()); let mut json = json::PrettyEncoder::new(&mut stdout); // unwrapping so IoError isn't ignored - unwrap_(krate.encode(&mut json)); + krate.encode(&mut json).unwrap(); } (krate, map) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index f61e85f3f3f..085fb816337 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -47,17 +47,6 @@ pub type Cmd = @crate_metadata; -// FIXME: remove unwrap_ after a snapshot -#[cfg(stage0)] -fn unwrap_(t: T) -> T { - t -} - -#[cfg(not(stage0))] -fn unwrap_(r: Result) -> T { - r.unwrap() -} - // A function that takes a def_id relative to the crate being searched and // returns a def_id relative to the compilation environment, i.e. if we hit a // def_id for an item defined in another crate, somebody needs to figure out @@ -70,7 +59,7 @@ fn lookup_hash<'a>(d: ebml::Doc<'a>, eq_fn: |&[u8]| -> bool, let table = reader::get_doc(index, tag_index_table); let hash_pos = table.start + (hash % 256 * 4) as uint; let pos = u64_from_be_bytes(d.data, hash_pos, 4) as uint; - let tagged_doc = unwrap_(reader::doc_at(d.data, pos)); + let tagged_doc = reader::doc_at(d.data, pos).unwrap(); let belt = tag_index_buckets_bucket_elt; @@ -78,7 +67,7 @@ fn lookup_hash<'a>(d: ebml::Doc<'a>, eq_fn: |&[u8]| -> bool, reader::tagged_docs(tagged_doc.doc, belt, |elt| { let pos = u64_from_be_bytes(elt.data, elt.start, 4) as uint; if eq_fn(elt.data.slice(elt.start + 4, elt.end)) { - ret = Some(unwrap_(reader::doc_at(d.data, pos)).doc); + ret = Some(reader::doc_at(d.data, pos).unwrap().doc); false } else { true @@ -864,7 +853,7 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances { let item_doc = lookup_item(id, data); let variance_doc = reader::get_doc(item_doc, tag_item_variances); let mut decoder = reader::Decoder(variance_doc); - unwrap_(Decodable::decode(&mut decoder)) + Decodable::decode(&mut decoder).unwrap() } pub fn get_provided_trait_methods(intr: @IdentInterner, cdata: Cmd, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 5b47f1f5621..234ee48a9e7 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -62,11 +62,6 @@ pub enum InlinedItemRef<'a> { IIForeignRef(&'a ast::ForeignItem) } -// FIXME: remove this Encoder type after a snapshot -#[cfg(stage0)] -pub type Encoder<'a> = writer::Encoder<'a>; - -#[cfg(not(stage0))] pub type Encoder<'a> = writer::Encoder<'a, MemWriter>; pub type EncodeInlinedItem<'a> = 'a |ecx: &EncodeContext, diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index fd72a5f838a..74742942b89 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -38,8 +38,6 @@ use std::cast; use std::cell::RefCell; use std::io::Seek; -// FIXME: remove this attr after snapshot -#[cfg(not(stage0))] use std::io::MemWriter; use std::rc::Rc; @@ -81,36 +79,8 @@ trait tr_intern { fn tr_intern(&self, xcx: &ExtendedDecodeContext) -> ast::DefId; } -// FIXME: remove this Encoder type after snapshot -#[cfg(stage0)] -pub type Encoder<'a> = writer::Encoder<'a>; - -#[cfg(not(stage0))] pub type Encoder<'a> = writer::Encoder<'a, MemWriter>; -// FIXME: remove unwrap_ and wrap_ after snapshot -#[cfg(stage0)] -fn unwrap_(t: T) -> T { - t -} - -#[cfg(not(stage0))] -fn unwrap_(r: Result) -> T { - r.unwrap() -} - -#[cfg(stage0)] -fn wrap_(t: T) -> T { - t -} - -#[cfg(not(stage0))] -fn wrap_(t: T) -> Result { - Ok(t) -} - - - // ______________________________________________________________________ // Top-level methods. @@ -171,7 +141,7 @@ pub fn decode_inlined_item(cdata: @cstore::crate_metadata, path_as_str.as_ref().map(|x| x.as_slice()) }); let mut ast_dsr = reader::Decoder(ast_doc); - let from_id_range = unwrap_(Decodable::decode(&mut ast_dsr)); + let from_id_range = Decodable::decode(&mut ast_dsr).unwrap(); let to_id_range = reserve_id_range(&dcx.tcx.sess, from_id_range); let xcx = &ExtendedDecodeContext { dcx: dcx, @@ -307,17 +277,9 @@ trait def_id_encoder_helpers { fn emit_def_id(&mut self, did: ast::DefId); } -#[cfg(stage0)] -impl def_id_encoder_helpers for S { - fn emit_def_id(&mut self, did: ast::DefId) { - did.encode(self) - } -} - -#[cfg(not(stage0))] impl, E> def_id_encoder_helpers for S { fn emit_def_id(&mut self, did: ast::DefId) { - unwrap_(did.encode(self)) + did.encode(self).unwrap() } } @@ -327,30 +289,15 @@ fn read_def_id_noxcx(&mut self, cdata: @cstore::crate_metadata) -> ast::DefId; } -#[cfg(stage0)] -impl def_id_decoder_helpers for D { - fn read_def_id(&mut self, xcx: &ExtendedDecodeContext) -> ast::DefId { - let did: ast::DefId = unwrap_(Decodable::decode(self)); - did.tr(xcx) - } - - fn read_def_id_noxcx(&mut self, - cdata: @cstore::crate_metadata) -> ast::DefId { - let did: ast::DefId = unwrap_(Decodable::decode(self)); - decoder::translate_def_id(cdata, did) - } -} - -#[cfg(not(stage0))] impl, E> def_id_decoder_helpers for D { fn read_def_id(&mut self, xcx: &ExtendedDecodeContext) -> ast::DefId { - let did: ast::DefId = unwrap_(Decodable::decode(self)); + let did: ast::DefId = Decodable::decode(self).unwrap(); did.tr(xcx) } fn read_def_id_noxcx(&mut self, cdata: @cstore::crate_metadata) -> ast::DefId { - let did: ast::DefId = unwrap_(Decodable::decode(self)); + let did: ast::DefId = Decodable::decode(self).unwrap(); decoder::translate_def_id(cdata, did) } } @@ -430,7 +377,7 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem { fn decode_ast(par_doc: ebml::Doc) -> ast::InlinedItem { let chi_doc = par_doc.get(c::tag_tree as uint); let mut d = reader::Decoder(chi_doc); - unwrap_(Decodable::decode(&mut d)) + Decodable::decode(&mut d).unwrap() } struct AstRenumberer<'a> { @@ -476,7 +423,7 @@ fn renumber_and_map_ast(xcx: &ExtendedDecodeContext, fn decode_def(xcx: &ExtendedDecodeContext, doc: ebml::Doc) -> ast::Def { let mut dsr = reader::Decoder(doc); - let def: ast::Def = unwrap_(Decodable::decode(&mut dsr)); + let def: ast::Def = Decodable::decode(&mut dsr).unwrap(); def.tr(xcx) } @@ -584,7 +531,7 @@ fn tr(&self, xcx: &ExtendedDecodeContext) -> ty::BoundRegion { // Encoding and decoding of freevar information fn encode_freevar_entry(ebml_w: &mut Encoder, fv: @freevar_entry) { - unwrap_((*fv).encode(ebml_w)) + (*fv).encode(ebml_w).unwrap(); } trait ebml_decoder_helper { @@ -595,7 +542,7 @@ fn read_freevar_entry(&mut self, xcx: &ExtendedDecodeContext) impl<'a> ebml_decoder_helper for reader::Decoder<'a> { fn read_freevar_entry(&mut self, xcx: &ExtendedDecodeContext) -> freevar_entry { - let fv: freevar_entry = unwrap_(Decodable::decode(self)); + let fv: freevar_entry = Decodable::decode(self).unwrap(); fv.tr(xcx) } } @@ -620,7 +567,7 @@ fn read_capture_var(&mut self, xcx: &ExtendedDecodeContext) impl<'a> capture_var_helper for reader::Decoder<'a> { fn read_capture_var(&mut self, xcx: &ExtendedDecodeContext) -> moves::CaptureVar { - let cvar: moves::CaptureVar = unwrap_(Decodable::decode(self)); + let cvar: moves::CaptureVar = Decodable::decode(self).unwrap(); cvar.tr(xcx) } } @@ -646,7 +593,7 @@ fn encode_method_callee(ecx: &e::EncodeContext, ebml_w: &mut Encoder, autoderef: u32, method: &MethodCallee) { - unwrap_(ebml_w.emit_struct("MethodCallee", 4, |ebml_w| { + ebml_w.emit_struct("MethodCallee", 4, |ebml_w| { ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| { autoderef.encode(ebml_w) }); @@ -654,34 +601,34 @@ fn encode_method_callee(ecx: &e::EncodeContext, method.origin.encode(ebml_w) }); ebml_w.emit_struct_field("ty", 2u, |ebml_w| { - wrap_(ebml_w.emit_ty(ecx, method.ty)) + Ok(ebml_w.emit_ty(ecx, method.ty)) }); ebml_w.emit_struct_field("substs", 3u, |ebml_w| { - wrap_(ebml_w.emit_substs(ecx, &method.substs)) + Ok(ebml_w.emit_substs(ecx, &method.substs)) }) - })); + }).unwrap(); } impl<'a> read_method_callee_helper for reader::Decoder<'a> { fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext) -> (u32, MethodCallee) { - unwrap_(self.read_struct("MethodCallee", 4, |this| { - let autoderef = unwrap_(this.read_struct_field("autoderef", 0, |this| { + self.read_struct("MethodCallee", 4, |this| { + let autoderef = this.read_struct_field("autoderef", 0, |this| { Decodable::decode(this) - })); - wrap_((autoderef, MethodCallee { - origin: unwrap_(this.read_struct_field("origin", 1, |this| { + }).unwrap(); + Ok((autoderef, MethodCallee { + origin: this.read_struct_field("origin", 1, |this| { let method_origin: MethodOrigin = - unwrap_(Decodable::decode(this)); - wrap_(method_origin.tr(xcx)) - })), - ty: unwrap_(this.read_struct_field("ty", 2, |this| { - wrap_(this.read_ty(xcx)) - })), - substs: unwrap_(this.read_struct_field("substs", 3, |this| { - wrap_(this.read_substs(xcx)) - })) + Decodable::decode(this).unwrap(); + Ok(method_origin.tr(xcx)) + }).unwrap(), + ty: this.read_struct_field("ty", 2, |this| { + Ok(this.read_ty(xcx)) + }).unwrap(), + substs: this.read_struct_field("substs", 3, |this| { + Ok(this.read_substs(xcx)) + }).unwrap() })) - })) + }).unwrap() } } @@ -716,14 +663,14 @@ fn encode_vtable_res_with_key(ecx: &e::EncodeContext, ebml_w: &mut Encoder, autoderef: u32, dr: typeck::vtable_res) { - unwrap_(ebml_w.emit_struct("VtableWithKey", 2, |ebml_w| { + ebml_w.emit_struct("VtableWithKey", 2, |ebml_w| { ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| { autoderef.encode(ebml_w) }); ebml_w.emit_struct_field("vtable_res", 1u, |ebml_w| { - wrap_(encode_vtable_res(ecx, ebml_w, dr)) + Ok(encode_vtable_res(ecx, ebml_w, dr)) }) - })) + }).unwrap() } pub fn encode_vtable_res(ecx: &e::EncodeContext, @@ -733,35 +680,35 @@ pub fn encode_vtable_res(ecx: &e::EncodeContext, // ty::t doesn't work, and there is no way (atm) to have // hand-written encoding routines combine with auto-generated // ones. perhaps we should fix this. - unwrap_(ebml_w.emit_from_vec(dr.as_slice(), |ebml_w, param_tables| { - wrap_(encode_vtable_param_res(ecx, ebml_w, *param_tables)) - })) + ebml_w.emit_from_vec(dr.as_slice(), |ebml_w, param_tables| { + Ok(encode_vtable_param_res(ecx, ebml_w, *param_tables)) + }).unwrap() } pub fn encode_vtable_param_res(ecx: &e::EncodeContext, ebml_w: &mut Encoder, param_tables: typeck::vtable_param_res) { - unwrap_(ebml_w.emit_from_vec(param_tables.as_slice(), |ebml_w, vtable_origin| { - wrap_(encode_vtable_origin(ecx, ebml_w, vtable_origin)) - })) + ebml_w.emit_from_vec(param_tables.as_slice(), |ebml_w, vtable_origin| { + Ok(encode_vtable_origin(ecx, ebml_w, vtable_origin)) + }).unwrap() } pub fn encode_vtable_origin(ecx: &e::EncodeContext, ebml_w: &mut Encoder, vtable_origin: &typeck::vtable_origin) { - unwrap_(ebml_w.emit_enum("vtable_origin", |ebml_w| { + ebml_w.emit_enum("vtable_origin", |ebml_w| { match *vtable_origin { typeck::vtable_static(def_id, ref tys, vtable_res) => { ebml_w.emit_enum_variant("vtable_static", 0u, 3u, |ebml_w| { ebml_w.emit_enum_variant_arg(0u, |ebml_w| { - wrap_(ebml_w.emit_def_id(def_id)) + Ok(ebml_w.emit_def_id(def_id)) }); ebml_w.emit_enum_variant_arg(1u, |ebml_w| { - wrap_(ebml_w.emit_tys(ecx, tys.as_slice())) + Ok(ebml_w.emit_tys(ecx, tys.as_slice())) }); ebml_w.emit_enum_variant_arg(2u, |ebml_w| { - wrap_(encode_vtable_res(ecx, ebml_w, vtable_res)) + Ok(encode_vtable_res(ecx, ebml_w, vtable_res)) }) }) } @@ -776,7 +723,7 @@ pub fn encode_vtable_origin(ecx: &e::EncodeContext, }) } } - })) + }).unwrap() } pub trait vtable_decoder_helpers { @@ -800,21 +747,22 @@ fn read_vtable_res_with_key(&mut self, tcx: &ty::ctxt, cdata: @cstore::crate_metadata) -> (u32, typeck::vtable_res) { - unwrap_(self.read_struct("VtableWithKey", 2, |this| { - let autoderef = unwrap_(this.read_struct_field("autoderef", 0, |this| { + self.read_struct("VtableWithKey", 2, |this| { + let autoderef = this.read_struct_field("autoderef", 0, |this| { Decodable::decode(this) - })); - wrap_((autoderef, unwrap_(this.read_struct_field("vtable_res", 1, |this| { - wrap_(this.read_vtable_res(tcx, cdata)) - })))) - })) + }).unwrap(); + Ok((autoderef, this.read_struct_field("vtable_res", 1, |this| { + Ok(this.read_vtable_res(tcx, cdata)) + }).unwrap())) + }).unwrap() } fn read_vtable_res(&mut self, tcx: &ty::ctxt, cdata: @cstore::crate_metadata) -> typeck::vtable_res { - @unwrap_(self.read_to_vec(|this| - wrap_(this.read_vtable_param_res(tcx, cdata)))) + @self.read_to_vec(|this| + Ok(this.read_vtable_param_res(tcx, cdata))) + .unwrap() .move_iter() .collect() } @@ -822,8 +770,9 @@ fn read_vtable_res(&mut self, fn read_vtable_param_res(&mut self, tcx: &ty::ctxt, cdata: @cstore::crate_metadata) -> typeck::vtable_param_res { - @unwrap_(self.read_to_vec(|this| - wrap_(this.read_vtable_origin(tcx, cdata)))) + @self.read_to_vec(|this| + Ok(this.read_vtable_origin(tcx, cdata))) + .unwrap() .move_iter() .collect() } @@ -831,40 +780,40 @@ fn read_vtable_param_res(&mut self, fn read_vtable_origin(&mut self, tcx: &ty::ctxt, cdata: @cstore::crate_metadata) -> typeck::vtable_origin { - unwrap_(self.read_enum("vtable_origin", |this| { + self.read_enum("vtable_origin", |this| { this.read_enum_variant(["vtable_static", "vtable_param", "vtable_self"], |this, i| { - wrap_(match i { + Ok(match i { 0 => { typeck::vtable_static( - unwrap_(this.read_enum_variant_arg(0u, |this| { - wrap_(this.read_def_id_noxcx(cdata)) - })), - unwrap_(this.read_enum_variant_arg(1u, |this| { - wrap_(this.read_tys_noxcx(tcx, cdata)) - })), - unwrap_(this.read_enum_variant_arg(2u, |this| { - wrap_(this.read_vtable_res(tcx, cdata)) - })) + this.read_enum_variant_arg(0u, |this| { + Ok(this.read_def_id_noxcx(cdata)) + }).unwrap(), + this.read_enum_variant_arg(1u, |this| { + Ok(this.read_tys_noxcx(tcx, cdata)) + }).unwrap(), + this.read_enum_variant_arg(2u, |this| { + Ok(this.read_vtable_res(tcx, cdata)) + }).unwrap() ) } 1 => { typeck::vtable_param( - unwrap_(this.read_enum_variant_arg(0u, |this| { + this.read_enum_variant_arg(0u, |this| { Decodable::decode(this) - })), - unwrap_(this.read_enum_variant_arg(1u, |this| { + }).unwrap(), + this.read_enum_variant_arg(1u, |this| { this.read_uint() - })) + }).unwrap() ) } // hard to avoid - user input _ => fail!("bad enum variant") }) }) - })) + }).unwrap() } } @@ -902,22 +851,22 @@ fn emit_tpbt(&mut self, impl<'a> ebml_writer_helpers for Encoder<'a> { fn emit_ty(&mut self, ecx: &e::EncodeContext, ty: ty::t) { - self.emit_opaque(|this| wrap_(e::write_type(ecx, this, ty))); + self.emit_opaque(|this| Ok(e::write_type(ecx, this, ty))); } fn emit_vstore(&mut self, ecx: &e::EncodeContext, vstore: ty::vstore) { - self.emit_opaque(|this| wrap_(e::write_vstore(ecx, this, vstore))); + self.emit_opaque(|this| Ok(e::write_vstore(ecx, this, vstore))); } fn emit_tys(&mut self, ecx: &e::EncodeContext, tys: &[ty::t]) { - self.emit_from_vec(tys, |this, ty| wrap_(this.emit_ty(ecx, *ty))); + self.emit_from_vec(tys, |this, ty| Ok(this.emit_ty(ecx, *ty))); } fn emit_type_param_def(&mut self, ecx: &e::EncodeContext, type_param_def: &ty::TypeParameterDef) { self.emit_opaque(|this| { - wrap_(tyencode::enc_type_param_def(this.writer, + Ok(tyencode::enc_type_param_def(this.writer, &ecx.ty_str_ctxt(), type_param_def)) }); @@ -932,7 +881,7 @@ fn emit_tpbt(&mut self, this.emit_struct_field("type_param_defs", 0, |this| { this.emit_from_vec(tpbt.generics.type_param_defs(), |this, type_param_def| { - wrap_(this.emit_type_param_def(ecx, type_param_def)) + Ok(this.emit_type_param_def(ecx, type_param_def)) }) }); this.emit_struct_field("region_param_defs", 1, |this| { @@ -941,13 +890,13 @@ fn emit_tpbt(&mut self, }) }); this.emit_struct_field("ty", 1, |this| { - wrap_(this.emit_ty(ecx, tpbt.ty)) + Ok(this.emit_ty(ecx, tpbt.ty)) }) }); } fn emit_substs(&mut self, ecx: &e::EncodeContext, substs: &ty::substs) { - self.emit_opaque(|this| wrap_(tyencode::enc_substs(this.writer, + self.emit_opaque(|this| Ok(tyencode::enc_substs(this.writer, &ecx.ty_str_ctxt(), substs))); } @@ -975,7 +924,7 @@ fn emit_auto_adjustment(&mut self, ecx: &e::EncodeContext, adj: &ty::AutoAdjustm this.emit_enum_variant_arg(2, |this| m.encode(this)); this.emit_enum_variant_arg(3, |this| b.encode(this)); this.emit_enum_variant_arg(4, |this| def_id.encode(this)); - this.emit_enum_variant_arg(5, |this| wrap_(this.emit_substs(ecx, substs))) + this.emit_enum_variant_arg(5, |this| Ok(this.emit_substs(ecx, substs))) }) } } @@ -1060,7 +1009,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, for def in tcx.def_map.borrow().find(&id).iter() { ebml_w.tag(c::tag_table_def, |ebml_w| { ebml_w.id(id); - ebml_w.tag(c::tag_table_val, |ebml_w| unwrap_((*def).encode(ebml_w))); + ebml_w.tag(c::tag_table_val, |ebml_w| (*def).encode(ebml_w).unwrap()); }) } @@ -1087,7 +1036,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, ebml_w.id(id); ebml_w.tag(c::tag_table_val, |ebml_w| { ebml_w.emit_from_vec(fv.as_slice(), |ebml_w, fv_entry| { - wrap_(encode_freevar_entry(ebml_w, *fv_entry)) + Ok(encode_freevar_entry(ebml_w, *fv_entry)) }); }) }) @@ -1218,20 +1167,21 @@ fn read_tys_noxcx(&mut self, impl<'a> ebml_decoder_decoder_helpers for reader::Decoder<'a> { fn read_ty_noxcx(&mut self, tcx: &ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t { - unwrap_(self.read_opaque(|_, doc| { - wrap_(tydecode::parse_ty_data( + self.read_opaque(|_, doc| { + Ok(tydecode::parse_ty_data( doc.data, cdata.cnum, doc.start, tcx, |_, id| decoder::translate_def_id(cdata, id))) - })) + }).unwrap() } fn read_tys_noxcx(&mut self, tcx: &ty::ctxt, cdata: @cstore::crate_metadata) -> Vec { - unwrap_(self.read_to_vec(|this| wrap_(this.read_ty_noxcx(tcx, cdata)) )) + self.read_to_vec(|this| Ok(this.read_ty_noxcx(tcx, cdata)) ) + .unwrap() .move_iter() .collect() } @@ -1242,7 +1192,7 @@ fn read_ty(&mut self, xcx: &ExtendedDecodeContext) -> ty::t { // context. However, we do not bother, because region types // are not used during trans. - return unwrap_(self.read_opaque(|this, doc| { + return self.read_opaque(|this, doc| { debug!("read_ty({})", type_string(doc)); let ty = tydecode::parse_ty_data( @@ -1252,8 +1202,8 @@ fn read_ty(&mut self, xcx: &ExtendedDecodeContext) -> ty::t { xcx.dcx.tcx, |s, a| this.convert_def_id(xcx, s, a)); - wrap_(ty) - })); + Ok(ty) + }).unwrap(); fn type_string(doc: ebml::Doc) -> ~str { let mut str = ~""; @@ -1265,95 +1215,96 @@ fn type_string(doc: ebml::Doc) -> ~str { } fn read_tys(&mut self, xcx: &ExtendedDecodeContext) -> Vec { - unwrap_(self.read_to_vec(|this| wrap_(this.read_ty(xcx)))).move_iter().collect() + self.read_to_vec(|this| Ok(this.read_ty(xcx))).unwrap().move_iter().collect() } fn read_type_param_def(&mut self, xcx: &ExtendedDecodeContext) -> ty::TypeParameterDef { - unwrap_(self.read_opaque(|this, doc| { - wrap_(tydecode::parse_type_param_def_data( + self.read_opaque(|this, doc| { + Ok(tydecode::parse_type_param_def_data( doc.data, doc.start, xcx.dcx.cdata.cnum, xcx.dcx.tcx, |s, a| this.convert_def_id(xcx, s, a))) - })) + }).unwrap() } fn read_ty_param_bounds_and_ty(&mut self, xcx: &ExtendedDecodeContext) -> ty::ty_param_bounds_and_ty { - unwrap_(self.read_struct("ty_param_bounds_and_ty", 2, |this| { - wrap_(ty::ty_param_bounds_and_ty { - generics: unwrap_(this.read_struct_field("generics", 0, |this| { + self.read_struct("ty_param_bounds_and_ty", 2, |this| { + Ok(ty::ty_param_bounds_and_ty { + generics: this.read_struct_field("generics", 0, |this| { this.read_struct("Generics", 2, |this| { - wrap_(ty::Generics { + Ok(ty::Generics { type_param_defs: - unwrap_(this.read_struct_field("type_param_defs", + this.read_struct_field("type_param_defs", 0, |this| { - wrap_(Rc::new(unwrap_(this.read_to_vec(|this| - wrap_(this.read_type_param_def(xcx)))) + Ok(Rc::new(this.read_to_vec(|this| + Ok(this.read_type_param_def(xcx))) + .unwrap() .move_iter() .collect())) - })), + }).unwrap(), region_param_defs: - unwrap_(this.read_struct_field("region_param_defs", + this.read_struct_field("region_param_defs", 1, |this| { Decodable::decode(this) - })) + }).unwrap() }) }) - })), - ty: unwrap_(this.read_struct_field("ty", 1, |this| { - wrap_(this.read_ty(xcx)) - })) + }).unwrap(), + ty: this.read_struct_field("ty", 1, |this| { + Ok(this.read_ty(xcx)) + }).unwrap() }) - })) + }).unwrap() } fn read_substs(&mut self, xcx: &ExtendedDecodeContext) -> ty::substs { - unwrap_(self.read_opaque(|this, doc| { - wrap_(tydecode::parse_substs_data(doc.data, + self.read_opaque(|this, doc| { + Ok(tydecode::parse_substs_data(doc.data, xcx.dcx.cdata.cnum, doc.start, xcx.dcx.tcx, |s, a| this.convert_def_id(xcx, s, a))) - })) + }).unwrap() } fn read_auto_adjustment(&mut self, xcx: &ExtendedDecodeContext) -> ty::AutoAdjustment { - unwrap_(self.read_enum("AutoAdjustment", |this| { + self.read_enum("AutoAdjustment", |this| { let variants = ["AutoAddEnv", "AutoDerefRef", "AutoObject"]; this.read_enum_variant(variants, |this, i| { - wrap_(match i { + Ok(match i { 0 => { let region: ty::Region = - unwrap_(this.read_enum_variant_arg(0, |this| Decodable::decode(this))); + this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap(); let sigil: ast::Sigil = - unwrap_(this.read_enum_variant_arg(1, |this| Decodable::decode(this))); + this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap(); ty:: AutoAddEnv(region.tr(xcx), sigil) } 1 => { let auto_deref_ref: ty::AutoDerefRef = - unwrap_(this.read_enum_variant_arg(0, |this| Decodable::decode(this))); + this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap(); ty::AutoDerefRef(auto_deref_ref.tr(xcx)) } 2 => { let sigil: ast::Sigil = - unwrap_(this.read_enum_variant_arg(0, |this| Decodable::decode(this))); + this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap(); let region: Option = - unwrap_(this.read_enum_variant_arg(1, |this| Decodable::decode(this))); + this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap(); let m: ast::Mutability = - unwrap_(this.read_enum_variant_arg(2, |this| Decodable::decode(this))); + this.read_enum_variant_arg(2, |this| Decodable::decode(this)).unwrap(); let b: ty::BuiltinBounds = - unwrap_(this.read_enum_variant_arg(3, |this| Decodable::decode(this))); + this.read_enum_variant_arg(3, |this| Decodable::decode(this)).unwrap(); let def_id: ast::DefId = - unwrap_(this.read_enum_variant_arg(4, |this| Decodable::decode(this))); - let substs = unwrap_( - this.read_enum_variant_arg(5, |this| wrap_(this.read_substs(xcx)))); + this.read_enum_variant_arg(4, |this| Decodable::decode(this)).unwrap(); + let substs = this.read_enum_variant_arg(5, |this| Ok(this.read_substs(xcx))) + .unwrap(); let region = match region { Some(r) => Some(r.tr(xcx)), @@ -1365,7 +1316,7 @@ fn read_auto_adjustment(&mut self, xcx: &ExtendedDecodeContext) -> ty::AutoAdjus _ => fail!("bad enum variant for ty::AutoAdjustment") }) }) - })) + }).unwrap() } fn convert_def_id(&mut self, @@ -1448,9 +1399,9 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext, dcx.tcx.node_type_substs.borrow_mut().insert(id, tys); } c::tag_table_freevars => { - let fv_info = @unwrap_(val_dsr.read_to_vec(|val_dsr| { - wrap_(@val_dsr.read_freevar_entry(xcx)) - })).move_iter().collect(); + let fv_info = @val_dsr.read_to_vec(|val_dsr| { + Ok(@val_dsr.read_freevar_entry(xcx)) + }).unwrap().move_iter().collect(); dcx.tcx.freevars.borrow_mut().insert(id, fv_info); } c::tag_table_tcache => { @@ -1486,8 +1437,9 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext, } c::tag_table_capture_map => { let cvars = - unwrap_(val_dsr.read_to_vec( - |val_dsr| wrap_(val_dsr.read_capture_var(xcx)))) + val_dsr.read_to_vec( + |val_dsr| Ok(val_dsr.read_capture_var(xcx))) + .unwrap() .move_iter() .collect(); dcx.maps.capture_map.borrow_mut().insert(id, Rc::new(cvars)); @@ -1519,7 +1471,7 @@ fn encode_item_ast(ebml_w: &mut Encoder, item: @ast::Item) { fn decode_item_ast(par_doc: ebml::Doc) -> @ast::Item { let chi_doc = par_doc.get(c::tag_tree as uint); let mut d = reader::Decoder(chi_doc); - @unwrap_(Decodable::decode(&mut d)) + @Decodable::decode(&mut d).unwrap() } #[cfg(test)] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 38b3901a0ee..d38b9a0db8b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -327,17 +327,6 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output { return pm.run_plugins(krate); } -// FIXME: remove unwrap_ after snapshot -#[cfg(stage0)] -fn unwrap_(t: T) -> T { - t -} - -#[cfg(not(stage0))] -fn unwrap_(r: Result) -> T { - r.unwrap() -} - /// This input format purely deserializes the json output file. No passes are /// run over the deserialized output. fn json_input(input: &str) -> Result { @@ -363,7 +352,7 @@ fn json_input(input: &str) -> Result { let krate = match obj.pop(&~"crate") { Some(json) => { let mut d = json::Decoder::new(json); - unwrap_(Decodable::decode(&mut d)) + Decodable::decode(&mut d).unwrap() } None => return Err(~"malformed json"), }; @@ -395,7 +384,7 @@ fn json_output(krate: clean::Crate, res: Vec , let mut w = MemWriter::new(); { let mut encoder = json::Encoder::new(&mut w as &mut io::Writer); - unwrap_(krate.encode(&mut encoder)); + krate.encode(&mut encoder).unwrap(); } str::from_utf8_owned(w.unwrap()).unwrap() }; diff --git a/src/libserialize/collection_impls_old.rs b/src/libserialize/collection_impls_old.rs deleted file mode 100644 index 5994fbc5d10..00000000000 --- a/src/libserialize/collection_impls_old.rs +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Implementations of serialization for structures found in libcollections - -use std::uint; -use std::default::Default; -use std::hash::{Hash, Hasher}; - -use {Decodable, Encodable, Decoder, Encoder}; -use collections::{DList, RingBuf, TreeMap, TreeSet, Deque, HashMap, HashSet, - TrieMap, TrieSet}; -use collections::enum_set::{EnumSet, CLike}; - -impl< - S: Encoder, - T: Encodable -> Encodable for DList { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)); - } - }) - } -} - -impl> Decodable for DList { - fn decode(d: &mut D) -> DList { - let mut list = DList::new(); - d.read_seq(|d, len| { - for i in range(0u, len) { - list.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - }); - list - } -} - -impl< - S: Encoder, - T: Encodable -> Encodable for RingBuf { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)); - } - }) - } -} - -impl> Decodable for RingBuf { - fn decode(d: &mut D) -> RingBuf { - let mut deque = RingBuf::new(); - d.read_seq(|d, len| { - for i in range(0u, len) { - deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - }); - deque - } -} - -impl< - E: Encoder, - K: Encodable + Eq + TotalOrd, - V: Encodable + Eq -> Encodable for TreeMap { - fn encode(&self, e: &mut E) { - e.emit_map(self.len(), |e| { - let mut i = 0; - for (key, val) in self.iter() { - e.emit_map_elt_key(i, |e| key.encode(e)); - e.emit_map_elt_val(i, |e| val.encode(e)); - i += 1; - } - }) - } -} - -impl< - D: Decoder, - K: Decodable + Eq + TotalOrd, - V: Decodable + Eq -> Decodable for TreeMap { - fn decode(d: &mut D) -> TreeMap { - d.read_map(|d, len| { - let mut map = TreeMap::new(); - for i in range(0u, len) { - let key = d.read_map_elt_key(i, |d| Decodable::decode(d)); - let val = d.read_map_elt_val(i, |d| Decodable::decode(d)); - map.insert(key, val); - } - map - }) - } -} - -impl< - S: Encoder, - T: Encodable + Eq + TotalOrd -> Encodable for TreeSet { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - let mut i = 0; - for e in self.iter() { - s.emit_seq_elt(i, |s| e.encode(s)); - i += 1; - } - }) - } -} - -impl< - D: Decoder, - T: Decodable + Eq + TotalOrd -> Decodable for TreeSet { - fn decode(d: &mut D) -> TreeSet { - d.read_seq(|d, len| { - let mut set = TreeSet::new(); - for i in range(0u, len) { - set.insert(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - set - }) - } -} - -impl< - S: Encoder, - T: Encodable + CLike -> Encodable for EnumSet { - fn encode(&self, s: &mut S) { - let mut bits = 0; - for item in self.iter() { - bits |= item.to_uint(); - } - s.emit_uint(bits); - } -} - -impl< - D: Decoder, - T: Decodable + CLike -> Decodable for EnumSet { - fn decode(d: &mut D) -> EnumSet { - let bits = d.read_uint(); - let mut set = EnumSet::empty(); - for bit in range(0, uint::BITS) { - if bits & (1 << bit) != 0 { - set.add(CLike::from_uint(1 << bit)); - } - } - set - } -} - -impl< - E: Encoder, - K: Encodable + Hash + TotalEq, - V: Encodable, - S, - H: Hasher -> Encodable for HashMap { - fn encode(&self, e: &mut E) { - e.emit_map(self.len(), |e| { - let mut i = 0; - for (key, val) in self.iter() { - e.emit_map_elt_key(i, |e| key.encode(e)); - e.emit_map_elt_val(i, |e| val.encode(e)); - i += 1; - } - }) - } -} - -impl< - D: Decoder, - K: Decodable + Hash + TotalEq, - V: Decodable, - S, - H: Hasher + Default -> Decodable for HashMap { - fn decode(d: &mut D) -> HashMap { - d.read_map(|d, len| { - let hasher = Default::default(); - let mut map = HashMap::with_capacity_and_hasher(len, hasher); - for i in range(0u, len) { - let key = d.read_map_elt_key(i, |d| Decodable::decode(d)); - let val = d.read_map_elt_val(i, |d| Decodable::decode(d)); - map.insert(key, val); - } - map - }) - } -} - -impl< - E: Encoder, - T: Encodable + Hash + TotalEq, - S, - H: Hasher -> Encodable for HashSet { - fn encode(&self, s: &mut E) { - s.emit_seq(self.len(), |s| { - let mut i = 0; - for e in self.iter() { - s.emit_seq_elt(i, |s| e.encode(s)); - i += 1; - } - }) - } -} - -impl< - D: Decoder, - T: Decodable + Hash + TotalEq, - S, - H: Hasher + Default -> Decodable for HashSet { - fn decode(d: &mut D) -> HashSet { - d.read_seq(|d, len| { - let mut set = HashSet::with_capacity_and_hasher(len, Default::default()); - for i in range(0u, len) { - set.insert(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - set - }) - } -} - -impl< - E: Encoder, - V: Encodable -> Encodable for TrieMap { - fn encode(&self, e: &mut E) { - e.emit_map(self.len(), |e| { - for (i, (key, val)) in self.iter().enumerate() { - e.emit_map_elt_key(i, |e| key.encode(e)); - e.emit_map_elt_val(i, |e| val.encode(e)); - } - }); - } -} - -impl< - D: Decoder, - V: Decodable -> Decodable for TrieMap { - fn decode(d: &mut D) -> TrieMap { - d.read_map(|d, len| { - let mut map = TrieMap::new(); - for i in range(0u, len) { - let key = d.read_map_elt_key(i, |d| Decodable::decode(d)); - let val = d.read_map_elt_val(i, |d| Decodable::decode(d)); - map.insert(key, val); - } - map - }) - } -} - -impl Encodable for TrieSet { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)); - } - }) - } -} - -impl Decodable for TrieSet { - fn decode(d: &mut D) -> TrieSet { - d.read_seq(|d, len| { - let mut set = TrieSet::new(); - for i in range(0u, len) { - set.insert(d.read_seq_elt(i, |d| Decodable::decode(d))); - } - set - }) - } -} - diff --git a/src/libserialize/ebml_old.rs b/src/libserialize/ebml_old.rs deleted file mode 100644 index 1c66960672f..00000000000 --- a/src/libserialize/ebml_old.rs +++ /dev/null @@ -1,1120 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[allow(missing_doc)]; - -use std::str; - -macro_rules! try( ($e:expr) => ( - match $e { Ok(e) => e, Err(e) => { self.last_error = Err(e); return } } -) ) - -// Simple Extensible Binary Markup Language (ebml) reader and writer on a -// cursor model. See the specification here: -// http://www.matroska.org/technical/specs/rfc/index.html - -// Common data structures -#[deriving(Clone)] -pub struct Doc<'a> { - data: &'a [u8], - start: uint, - end: uint, -} - -impl<'doc> Doc<'doc> { - pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> { - reader::get_doc(*self, tag) - } - - pub fn as_str_slice<'a>(&'a self) -> &'a str { - str::from_utf8(self.data.slice(self.start, self.end)).unwrap() - } - - pub fn as_str(&self) -> ~str { - self.as_str_slice().to_owned() - } -} - -pub struct TaggedDoc<'a> { - priv tag: uint, - doc: Doc<'a>, -} - -pub enum EbmlEncoderTag { - EsUint, // 0 - EsU64, // 1 - EsU32, // 2 - EsU16, // 3 - EsU8, // 4 - EsInt, // 5 - EsI64, // 6 - EsI32, // 7 - EsI16, // 8 - EsI8, // 9 - EsBool, // 10 - EsChar, // 11 - EsStr, // 12 - EsF64, // 13 - EsF32, // 14 - EsFloat, // 15 - EsEnum, // 16 - EsEnumVid, // 17 - EsEnumBody, // 18 - EsVec, // 19 - EsVecLen, // 20 - EsVecElt, // 21 - EsMap, // 22 - EsMapLen, // 23 - EsMapKey, // 24 - EsMapVal, // 25 - - EsOpaque, - - EsLabel, // Used only when debugging -} -// -------------------------------------- - -pub mod reader { - use std::char; - - use std::cast::transmute; - use std::int; - use std::option::{None, Option, Some}; - use std::io::extensions::u64_from_be_bytes; - - use serialize; - - use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey, - EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8, - EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint, - EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc }; - - // ebml reading - - pub struct Res { - val: uint, - next: uint - } - - #[inline(never)] - fn vuint_at_slow(data: &[u8], start: uint) -> Res { - let a = data[start]; - if a & 0x80u8 != 0u8 { - return Res {val: (a & 0x7fu8) as uint, next: start + 1u}; - } - if a & 0x40u8 != 0u8 { - return Res {val: ((a & 0x3fu8) as uint) << 8u | - (data[start + 1u] as uint), - next: start + 2u}; - } - if a & 0x20u8 != 0u8 { - return Res {val: ((a & 0x1fu8) as uint) << 16u | - (data[start + 1u] as uint) << 8u | - (data[start + 2u] as uint), - next: start + 3u}; - } - if a & 0x10u8 != 0u8 { - return Res {val: ((a & 0x0fu8) as uint) << 24u | - (data[start + 1u] as uint) << 16u | - (data[start + 2u] as uint) << 8u | - (data[start + 3u] as uint), - next: start + 4u}; - } - fail!("vint too big"); - } - - pub fn vuint_at(data: &[u8], start: uint) -> Res { - use std::mem::from_be32; - - if data.len() - start < 4 { - return vuint_at_slow(data, start); - } - - // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/ - // The Element IDs are parsed by reading a big endian u32 positioned at data[start]. - // Using the four most significant bits of the u32 we lookup in the table below how the - // element ID should be derived from it. - // - // The table stores tuples (shift, mask) where shift is the number the u32 should be right - // shifted with and mask is the value the right shifted value should be masked with. - // If for example the most significant bit is set this means it's a class A ID and the u32 - // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at - // index 0x8 - 0xF (four bit numbers where the most significant bit is set). - // - // By storing the number of shifts and masks in a table instead of checking in order if - // the most significant bit is set, the second most significant bit is set etc. we can - // replace up to three "and+branch" with a single table lookup which gives us a measured - // speedup of around 2x on x86_64. - static SHIFT_MASK_TABLE: [(u32, u32), ..16] = [ - (0, 0x0), (0, 0x0fffffff), - (8, 0x1fffff), (8, 0x1fffff), - (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), - (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f), - (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f) - ]; - - unsafe { - let ptr = data.as_ptr().offset(start as int) as *i32; - let val = from_be32(*ptr) as u32; - - let i = (val >> 28u) as uint; - let (shift, mask) = SHIFT_MASK_TABLE[i]; - Res { - val: ((val >> shift) & mask) as uint, - next: start + (((32 - shift) >> 3) as uint) - } - } - } - - pub fn Doc<'a>(data: &'a [u8]) -> Doc<'a> { - Doc { data: data, start: 0u, end: data.len() } - } - - pub fn doc_at<'a>(data: &'a [u8], start: uint) -> TaggedDoc<'a> { - let elt_tag = vuint_at(data, start); - let elt_size = vuint_at(data, elt_tag.next); - let end = elt_size.next + elt_size.val; - TaggedDoc { - tag: elt_tag.val, - doc: Doc { data: data, start: elt_size.next, end: end } - } - } - - pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option> { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(d.data, pos); - let elt_size = vuint_at(d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - return Some(Doc { data: d.data, start: elt_size.next, - end: pos }); - } - } - None - } - - pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> { - match maybe_get_doc(d, tg) { - Some(d) => d, - None => { - error!("failed to find block with tag {}", tg); - fail!(); - } - } - } - - pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(d.data, pos); - let elt_size = vuint_at(d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - let doc = Doc { data: d.data, start: elt_size.next, end: pos }; - if !it(elt_tag.val, doc) { - return false; - } - } - return true; - } - - pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(d.data, pos); - let elt_size = vuint_at(d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - let doc = Doc { data: d.data, start: elt_size.next, - end: pos }; - if !it(doc) { - return false; - } - } - } - return true; - } - - pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T { - f(d.data.slice(d.start, d.end)) - } - - - pub fn doc_as_u8(d: Doc) -> u8 { - assert_eq!(d.end, d.start + 1u); - d.data[d.start] - } - - pub fn doc_as_u16(d: Doc) -> u16 { - assert_eq!(d.end, d.start + 2u); - u64_from_be_bytes(d.data, d.start, 2u) as u16 - } - - pub fn doc_as_u32(d: Doc) -> u32 { - assert_eq!(d.end, d.start + 4u); - u64_from_be_bytes(d.data, d.start, 4u) as u32 - } - - pub fn doc_as_u64(d: Doc) -> u64 { - assert_eq!(d.end, d.start + 8u); - u64_from_be_bytes(d.data, d.start, 8u) - } - - pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } - pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } - pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } - pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } - - pub struct Decoder<'a> { - priv parent: Doc<'a>, - priv pos: uint, - } - - pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> { - Decoder { - parent: d, - pos: d.start - } - } - - impl<'doc> Decoder<'doc> { - fn _check_label(&mut self, lbl: &str) { - if self.pos < self.parent.end { - let TaggedDoc { tag: r_tag, doc: r_doc } = - doc_at(self.parent.data, self.pos); - - if r_tag == (EsLabel as uint) { - self.pos = r_doc.end; - let str = r_doc.as_str_slice(); - if lbl != str { - fail!("Expected label {} but found {}", lbl, str); - } - } - } - } - - fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc<'doc> { - debug!(". next_doc(exp_tag={:?})", exp_tag); - if self.pos >= self.parent.end { - fail!("no more documents in current node!"); - } - let TaggedDoc { tag: r_tag, doc: r_doc } = - doc_at(self.parent.data, self.pos); - debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}", - self.parent.start, - self.parent.end, - self.pos, - r_tag, - r_doc.start, - r_doc.end); - if r_tag != (exp_tag as uint) { - fail!("expected EBML doc with tag {:?} but found tag {:?}", - exp_tag, r_tag); - } - if r_doc.end > self.parent.end { - fail!("invalid EBML, child extends to {:#x}, parent to {:#x}", - r_doc.end, self.parent.end); - } - self.pos = r_doc.end; - r_doc - } - - fn push_doc(&mut self, exp_tag: EbmlEncoderTag, - f: |&mut Decoder<'doc>| -> T) -> T { - let d = self.next_doc(exp_tag); - let old_parent = self.parent; - let old_pos = self.pos; - self.parent = d; - self.pos = d.start; - let r = f(self); - self.parent = old_parent; - self.pos = old_pos; - r - } - - fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> uint { - let r = doc_as_u32(self.next_doc(exp_tag)); - debug!("_next_uint exp_tag={:?} result={}", exp_tag, r); - r as uint - } - - pub fn read_opaque(&mut self, op: |&mut Decoder<'doc>, Doc| -> R) -> R { - let doc = self.next_doc(EsOpaque); - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = doc.start; - - let result = op(self, doc); - - self.parent = old_parent; - self.pos = old_pos; - result - } - } - - impl<'doc> serialize::Decoder for Decoder<'doc> { - fn read_nil(&mut self) -> () { () } - - fn read_u64(&mut self) -> u64 { doc_as_u64(self.next_doc(EsU64)) } - fn read_u32(&mut self) -> u32 { doc_as_u32(self.next_doc(EsU32)) } - fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) } - fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) } - fn read_uint(&mut self) -> uint { - let v = doc_as_u64(self.next_doc(EsUint)); - if v > (::std::uint::MAX as u64) { - fail!("uint {} too large for this architecture", v); - } - v as uint - } - - fn read_i64(&mut self) -> i64 { - doc_as_u64(self.next_doc(EsI64)) as i64 - } - fn read_i32(&mut self) -> i32 { - doc_as_u32(self.next_doc(EsI32)) as i32 - } - fn read_i16(&mut self) -> i16 { - doc_as_u16(self.next_doc(EsI16)) as i16 - } - fn read_i8 (&mut self) -> i8 { - doc_as_u8(self.next_doc(EsI8 )) as i8 - } - fn read_int(&mut self) -> int { - let v = doc_as_u64(self.next_doc(EsInt)) as i64; - if v > (int::MAX as i64) || v < (int::MIN as i64) { - debug!("FIXME \\#6122: Removing this makes this function miscompile"); - fail!("int {} out of range for this architecture", v); - } - v as int - } - - fn read_bool(&mut self) -> bool { - doc_as_u8(self.next_doc(EsBool)) != 0 - } - - fn read_f64(&mut self) -> f64 { - let bits = doc_as_u64(self.next_doc(EsF64)); - unsafe { transmute(bits) } - } - fn read_f32(&mut self) -> f32 { - let bits = doc_as_u32(self.next_doc(EsF32)); - unsafe { transmute(bits) } - } - fn read_char(&mut self) -> char { - char::from_u32(doc_as_u32(self.next_doc(EsChar))).unwrap() - } - fn read_str(&mut self) -> ~str { - self.next_doc(EsStr).as_str() - } - - // Compound types: - fn read_enum(&mut self, name: &str, f: |&mut Decoder<'doc>| -> T) -> T { - debug!("read_enum({})", name); - self._check_label(name); - - let doc = self.next_doc(EsEnum); - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = self.parent.start; - - let result = f(self); - - self.parent = old_parent; - self.pos = old_pos; - result - } - - fn read_enum_variant(&mut self, - _: &[&str], - f: |&mut Decoder<'doc>, uint| -> T) - -> T { - debug!("read_enum_variant()"); - let idx = self._next_uint(EsEnumVid); - debug!(" idx={}", idx); - - let doc = self.next_doc(EsEnumBody); - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = self.parent.start; - - let result = f(self, idx); - - self.parent = old_parent; - self.pos = old_pos; - result - } - - fn read_enum_variant_arg(&mut self, - idx: uint, - f: |&mut Decoder<'doc>| -> T) -> T { - debug!("read_enum_variant_arg(idx={})", idx); - f(self) - } - - fn read_enum_struct_variant(&mut self, - _: &[&str], - f: |&mut Decoder<'doc>, uint| -> T) - -> T { - debug!("read_enum_struct_variant()"); - let idx = self._next_uint(EsEnumVid); - debug!(" idx={}", idx); - - let doc = self.next_doc(EsEnumBody); - - let (old_parent, old_pos) = (self.parent, self.pos); - self.parent = doc; - self.pos = self.parent.start; - - let result = f(self, idx); - - self.parent = old_parent; - self.pos = old_pos; - result - } - - fn read_enum_struct_variant_field(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx); - f(self) - } - - fn read_struct(&mut self, - name: &str, - _: uint, - f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_struct(name={})", name); - f(self) - } - - fn read_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_struct_field(name={}, idx={})", name, idx); - self._check_label(name); - f(self) - } - - fn read_tuple(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T { - debug!("read_tuple()"); - self.read_seq(f) - } - - fn read_tuple_arg(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_tuple_arg(idx={})", idx); - self.read_seq_elt(idx, f) - } - - fn read_tuple_struct(&mut self, - name: &str, - f: |&mut Decoder<'doc>, uint| -> T) - -> T { - debug!("read_tuple_struct(name={})", name); - self.read_tuple(f) - } - - fn read_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_tuple_struct_arg(idx={})", idx); - self.read_tuple_arg(idx, f) - } - - fn read_option(&mut self, f: |&mut Decoder<'doc>, bool| -> T) -> T { - debug!("read_option()"); - self.read_enum("Option", |this| { - this.read_enum_variant(["None", "Some"], |this, idx| { - match idx { - 0 => f(this, false), - 1 => f(this, true), - _ => fail!(), - } - }) - }) - } - - fn read_seq(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T { - debug!("read_seq()"); - self.push_doc(EsVec, |d| { - let len = d._next_uint(EsVecLen); - debug!(" len={}", len); - f(d, len) - }) - } - - fn read_seq_elt(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_seq_elt(idx={})", idx); - self.push_doc(EsVecElt, f) - } - - fn read_map(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T { - debug!("read_map()"); - self.push_doc(EsMap, |d| { - let len = d._next_uint(EsMapLen); - debug!(" len={}", len); - f(d, len) - }) - } - - fn read_map_elt_key(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_map_elt_key(idx={})", idx); - self.push_doc(EsMapKey, f) - } - - fn read_map_elt_val(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T) - -> T { - debug!("read_map_elt_val(idx={})", idx); - self.push_doc(EsMapVal, f) - } - } -} - -pub mod writer { - use std::cast; - use std::clone::Clone; - use std::io; - use std::io::{Writer, Seek}; - use std::io::MemWriter; - use std::io::extensions::u64_to_be_bytes; - - use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey, - EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8, - EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint, - EsOpaque, EsLabel, EbmlEncoderTag }; - - use serialize; - - // ebml writing - pub struct Encoder<'a> { - // FIXME(#5665): this should take a trait object. Note that if you - // delete this comment you should consider removing the - // unwrap()'s below of the results of the calls to - // write(). We're guaranteed that writing into a MemWriter - // won't fail, but this is not true for all I/O streams in - // general. - writer: &'a mut MemWriter, - priv size_positions: ~[uint], - last_error: io::IoResult<()>, - } - - fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) { - match size { - 1u => w.write(&[0x80u8 | (n as u8)]), - 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]), - 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8, - n as u8]), - 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8, - (n >> 8_u) as u8, n as u8]), - _ => fail!("vint to write too big: {}", n) - }.unwrap() - } - - fn write_vuint(w: &mut MemWriter, n: uint) { - if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; } - if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; } - if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; } - if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; } - fail!("vint to write too big: {}", n); - } - - pub fn Encoder<'a>(w: &'a mut MemWriter) -> Encoder<'a> { - let size_positions: ~[uint] = ~[]; - Encoder { - writer: w, - size_positions: size_positions, - last_error: Ok(()), - } - } - - // FIXME (#2741): Provide a function to write the standard ebml header. - impl<'a> Encoder<'a> { - /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME. - pub unsafe fn unsafe_clone(&self) -> Encoder<'a> { - Encoder { - writer: cast::transmute_copy(&self.writer), - size_positions: self.size_positions.clone(), - last_error: Ok(()), - } - } - - pub fn start_tag(&mut self, tag_id: uint) { - debug!("Start tag {}", tag_id); - - // Write the enum ID: - write_vuint(self.writer, tag_id); - - // Write a placeholder four-byte size. - self.size_positions.push(try!(self.writer.tell()) as uint); - let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8]; - try!(self.writer.write(zeroes)); - } - - pub fn end_tag(&mut self) { - let last_size_pos = self.size_positions.pop().unwrap(); - let cur_pos = try!(self.writer.tell()); - try!(self.writer.seek(last_size_pos as i64, io::SeekSet)); - let size = cur_pos as uint - last_size_pos - 4; - write_sized_vuint(self.writer, size, 4u); - try!(self.writer.seek(cur_pos as i64, io::SeekSet)); - - debug!("End tag (size = {})", size); - } - - pub fn wr_tag(&mut self, tag_id: uint, blk: ||) { - self.start_tag(tag_id); - blk(); - self.end_tag(); - } - - pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) { - write_vuint(self.writer, tag_id); - write_vuint(self.writer, b.len()); - self.writer.write(b).unwrap(); - } - - pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) { - u64_to_be_bytes(v, 8u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) { - u64_to_be_bytes(v as u64, 4u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) { - u64_to_be_bytes(v as u64, 2u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) { - self.wr_tagged_bytes(tag_id, &[v]); - } - - pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) { - u64_to_be_bytes(v as u64, 8u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) { - u64_to_be_bytes(v as u64, 4u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) { - u64_to_be_bytes(v as u64, 2u, |v| { - self.wr_tagged_bytes(tag_id, v); - }) - } - - pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) { - self.wr_tagged_bytes(tag_id, &[v as u8]); - } - - pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) { - self.wr_tagged_bytes(tag_id, v.as_bytes()); - } - - pub fn wr_bytes(&mut self, b: &[u8]) { - debug!("Write {} bytes", b.len()); - self.writer.write(b).unwrap(); - } - - pub fn wr_str(&mut self, s: &str) { - debug!("Write str: {}", s); - self.writer.write(s.as_bytes()).unwrap(); - } - } - - // FIXME (#2743): optionally perform "relaxations" on end_tag to more - // efficiently encode sizes; this is a fixed point iteration - - // Set to true to generate more debugging in EBML code. - // Totally lame approach. - static DEBUG: bool = true; - - impl<'a> Encoder<'a> { - // used internally to emit things like the vector length and so on - fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) { - assert!(v <= 0xFFFF_FFFF_u); - self.wr_tagged_u32(t as uint, v as u32); - } - - fn _emit_label(&mut self, label: &str) { - // There are various strings that we have access to, such as - // the name of a record field, which do not actually appear in - // the encoded EBML (normally). This is just for - // efficiency. When debugging, though, we can emit such - // labels and then they will be checked by decoder to - // try and check failures more quickly. - if DEBUG { self.wr_tagged_str(EsLabel as uint, label) } - } - - pub fn emit_opaque(&mut self, f: |&mut Encoder|) { - self.start_tag(EsOpaque as uint); - f(self); - self.end_tag(); - } - } - - impl<'a> serialize::Encoder for Encoder<'a> { - fn emit_nil(&mut self) {} - - fn emit_uint(&mut self, v: uint) { - self.wr_tagged_u64(EsUint as uint, v as u64); - } - fn emit_u64(&mut self, v: u64) { - self.wr_tagged_u64(EsU64 as uint, v); - } - fn emit_u32(&mut self, v: u32) { - self.wr_tagged_u32(EsU32 as uint, v); - } - fn emit_u16(&mut self, v: u16) { - self.wr_tagged_u16(EsU16 as uint, v); - } - fn emit_u8(&mut self, v: u8) { - self.wr_tagged_u8(EsU8 as uint, v); - } - - fn emit_int(&mut self, v: int) { - self.wr_tagged_i64(EsInt as uint, v as i64); - } - fn emit_i64(&mut self, v: i64) { - self.wr_tagged_i64(EsI64 as uint, v); - } - fn emit_i32(&mut self, v: i32) { - self.wr_tagged_i32(EsI32 as uint, v); - } - fn emit_i16(&mut self, v: i16) { - self.wr_tagged_i16(EsI16 as uint, v); - } - fn emit_i8(&mut self, v: i8) { - self.wr_tagged_i8(EsI8 as uint, v); - } - - fn emit_bool(&mut self, v: bool) { - self.wr_tagged_u8(EsBool as uint, v as u8) - } - - fn emit_f64(&mut self, v: f64) { - let bits = unsafe { cast::transmute(v) }; - self.wr_tagged_u64(EsF64 as uint, bits); - } - fn emit_f32(&mut self, v: f32) { - let bits = unsafe { cast::transmute(v) }; - self.wr_tagged_u32(EsF32 as uint, bits); - } - fn emit_char(&mut self, v: char) { - self.wr_tagged_u32(EsChar as uint, v as u32); - } - - fn emit_str(&mut self, v: &str) { - self.wr_tagged_str(EsStr as uint, v) - } - - fn emit_enum(&mut self, name: &str, f: |&mut Encoder<'a>|) { - self._emit_label(name); - self.start_tag(EsEnum as uint); - f(self); - self.end_tag(); - } - - fn emit_enum_variant(&mut self, - _: &str, - v_id: uint, - _: uint, - f: |&mut Encoder<'a>|) { - self._emit_tagged_uint(EsEnumVid, v_id); - self.start_tag(EsEnumBody as uint); - f(self); - self.end_tag(); - } - - fn emit_enum_variant_arg(&mut self, _: uint, f: |&mut Encoder<'a>|) { - f(self) - } - - fn emit_enum_struct_variant(&mut self, - v_name: &str, - v_id: uint, - cnt: uint, - f: |&mut Encoder<'a>|) { - self.emit_enum_variant(v_name, v_id, cnt, f) - } - - fn emit_enum_struct_variant_field(&mut self, - _: &str, - idx: uint, - f: |&mut Encoder<'a>|) { - self.emit_enum_variant_arg(idx, f) - } - - fn emit_struct(&mut self, - _: &str, - _len: uint, - f: |&mut Encoder<'a>|) { - f(self) - } - - fn emit_struct_field(&mut self, - name: &str, - _: uint, - f: |&mut Encoder<'a>|) { - self._emit_label(name); - f(self) - } - - fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) { - self.emit_seq(len, f) - } - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) { - self.emit_seq_elt(idx, f) - } - - fn emit_tuple_struct(&mut self, - _: &str, - len: uint, - f: |&mut Encoder<'a>|) { - self.emit_seq(len, f) - } - fn emit_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut Encoder<'a>|) { - self.emit_seq_elt(idx, f) - } - - fn emit_option(&mut self, f: |&mut Encoder<'a>|) { - self.emit_enum("Option", f); - } - fn emit_option_none(&mut self) { - self.emit_enum_variant("None", 0, 0, |_| ()) - } - fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) { - self.emit_enum_variant("Some", 1, 1, f) - } - - fn emit_seq(&mut self, len: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsVec as uint); - self._emit_tagged_uint(EsVecLen, len); - f(self); - self.end_tag(); - } - - fn emit_seq_elt(&mut self, _idx: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsVecElt as uint); - f(self); - self.end_tag(); - } - - fn emit_map(&mut self, len: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsMap as uint); - self._emit_tagged_uint(EsMapLen, len); - f(self); - self.end_tag(); - } - - fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsMapKey as uint); - f(self); - self.end_tag(); - } - - fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) { - self.start_tag(EsMapVal as uint); - f(self); - self.end_tag(); - } - } -} - -// ___________________________________________________________________________ -// Testing - -#[cfg(test)] -mod tests { - use ebml::reader; - use ebml::writer; - use {Encodable, Decodable}; - - use std::io::MemWriter; - use std::option::{None, Option, Some}; - - #[test] - fn test_vuint_at() { - let data = [ - 0x80, - 0xff, - 0x40, 0x00, - 0x7f, 0xff, - 0x20, 0x00, 0x00, - 0x3f, 0xff, 0xff, - 0x10, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff - ]; - - let mut res: reader::Res; - - // Class A - res = reader::vuint_at(data, 0); - assert_eq!(res.val, 0); - assert_eq!(res.next, 1); - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, (1 << 7) - 1); - assert_eq!(res.next, 2); - - // Class B - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, 0); - assert_eq!(res.next, 4); - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, (1 << 14) - 1); - assert_eq!(res.next, 6); - - // Class C - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, 0); - assert_eq!(res.next, 9); - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, (1 << 21) - 1); - assert_eq!(res.next, 12); - - // Class D - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, 0); - assert_eq!(res.next, 16); - res = reader::vuint_at(data, res.next); - assert_eq!(res.val, (1 << 28) - 1); - assert_eq!(res.next, 20); - } - - #[test] - fn test_option_int() { - fn test_v(v: Option) { - debug!("v == {:?}", v); - let mut wr = MemWriter::new(); - { - let mut ebml_w = writer::Encoder(&mut wr); - v.encode(&mut ebml_w); - } - let ebml_doc = reader::Doc(wr.get_ref()); - let mut deser = reader::Decoder(ebml_doc); - let v1 = Decodable::decode(&mut deser); - debug!("v1 == {:?}", v1); - assert_eq!(v, v1); - } - - test_v(Some(22)); - test_v(None); - test_v(Some(3)); - } -} - -#[cfg(test)] -mod bench { - extern crate test; - use self::test::BenchHarness; - use ebml::reader; - - #[bench] - pub fn vuint_at_A_aligned(bh: &mut BenchHarness) { - use std::slice; - let data = slice::from_fn(4*100, |i| { - match i % 2 { - 0 => 0x80u8, - _ => i as u8, - } - }); - let mut sum = 0u; - bh.iter(|| { - let mut i = 0; - while i < data.len() { - sum += reader::vuint_at(data, i).val; - i += 4; - } - }); - } - - #[bench] - pub fn vuint_at_A_unaligned(bh: &mut BenchHarness) { - use std::slice; - let data = slice::from_fn(4*100+1, |i| { - match i % 2 { - 1 => 0x80u8, - _ => i as u8 - } - }); - let mut sum = 0u; - bh.iter(|| { - let mut i = 1; - while i < data.len() { - sum += reader::vuint_at(data, i).val; - i += 4; - } - }); - } - - #[bench] - pub fn vuint_at_D_aligned(bh: &mut BenchHarness) { - use std::slice; - let data = slice::from_fn(4*100, |i| { - match i % 4 { - 0 => 0x10u8, - 3 => i as u8, - _ => 0u8 - } - }); - let mut sum = 0u; - bh.iter(|| { - let mut i = 0; - while i < data.len() { - sum += reader::vuint_at(data, i).val; - i += 4; - } - }); - } - - #[bench] - pub fn vuint_at_D_unaligned(bh: &mut BenchHarness) { - use std::slice; - let data = slice::from_fn(4*100+1, |i| { - match i % 4 { - 1 => 0x10u8, - 0 => i as u8, - _ => 0u8 - } - }); - let mut sum = 0u; - bh.iter(|| { - let mut i = 1; - while i < data.len() { - sum += reader::vuint_at(data, i).val; - i += 4; - } - }); - } -} - diff --git a/src/libserialize/json_old.rs b/src/libserialize/json_old.rs deleted file mode 100644 index cc4c86599fa..00000000000 --- a/src/libserialize/json_old.rs +++ /dev/null @@ -1,2606 +0,0 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Rust JSON serialization library -// Copyright (c) 2011 Google Inc. - -#[forbid(non_camel_case_types)]; -#[allow(missing_doc)]; - -/*! -JSON parsing and serialization - -# What is JSON? - -JSON (JavaScript Object Notation) is a way to write data in Javascript. -Like XML it allows one to encode structured data in a text format that can be read by humans easily. -Its native compatibility with JavaScript and its simple syntax make it used widely. - -Json data are encoded in a form of "key":"value". -Data types that can be encoded are JavaScript types : -boolean (`true` or `false`), number (`f64`), string, array, object, null. -An object is a series of string keys mapping to values, in `"key": value` format. -Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). -A simple JSON document encoding a person, his/her age, address and phone numbers could look like: - -```ignore -{ - "FirstName": "John", - "LastName": "Doe", - "Age": 43, - "Address": { - "Street": "Downing Street 10", - "City": "London", - "Country": "Great Britain" - }, - "PhoneNumbers": [ - "+44 1234567", - "+44 2345678" - ] -} -``` - -# Rust Type-based Encoding and Decoding - -Rust provides a mechanism for low boilerplate encoding & decoding -of values to and from JSON via the serialization API. -To be able to encode a piece of data, it must implement the `serialize::Encodable` trait. -To be able to decode a piece of data, it must implement the `serialize::Decodable` trait. -The Rust compiler provides an annotation to automatically generate -the code for these traits: `#[deriving(Decodable, Encodable)]` - -To encode using Encodable : - -```rust -use std::io; -use serialize::{json, Encodable}; - - #[deriving(Encodable)] - pub struct TestStruct { - data_str: ~str, - } - -fn main() { - let to_encode_object = TestStruct{data_str:~"example of string to encode"}; - let mut m = io::MemWriter::new(); - { - let mut encoder = json::Encoder::new(&mut m as &mut std::io::Writer); - to_encode_object.encode(&mut encoder); - } -} -``` - -Two wrapper functions are provided to encode a Encodable object -into a string (~str) or buffer (~[u8]): `str_encode(&m)` and `buffer_encode(&m)`. - -```rust -use serialize::json; -let to_encode_object = ~"example of string to encode"; -let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object); -``` - -JSON API provide an enum `json::Json` and a trait `ToJson` to encode object. -The trait `ToJson` encode object into a container `json::Json` and the API provide writer -to encode them into a stream or a string ... - -When using `ToJson` the `Encodable` trait implementation is not mandatory. - -A basic `ToJson` example using a TreeMap of attribute name / attribute value: - - -```rust -extern crate collections; -extern crate serialize; - -use serialize::json; -use serialize::json::ToJson; -use collections::TreeMap; - -pub struct MyStruct { - attr1: u8, - attr2: ~str, -} - -impl ToJson for MyStruct { - fn to_json( &self ) -> json::Json { - let mut d = ~TreeMap::new(); - d.insert(~"attr1", self.attr1.to_json()); - d.insert(~"attr2", self.attr2.to_json()); - json::Object(d) - } -} - -fn main() { - let test2: MyStruct = MyStruct {attr1: 1, attr2:~"test"}; - let tjson: json::Json = test2.to_json(); - let json_str: ~str = tjson.to_str(); -} -``` - -To decode a JSON string using `Decodable` trait : - -```rust -extern crate serialize; -use serialize::{json, Decodable}; - -#[deriving(Decodable)] -pub struct MyStruct { - attr1: u8, - attr2: ~str, -} - -fn main() { - let json_str_to_decode: ~str = - ~"{\"attr1\":1,\"attr2\":\"toto\"}"; - let json_object = json::from_str(json_str_to_decode); - let mut decoder = json::Decoder::new(json_object.unwrap()); - let decoded_object: MyStruct = Decodable::decode(&mut decoder); // create the final object -} -``` - -# Examples of use - -## Using Autoserialization - -Create a struct called TestStruct1 and serialize and deserialize it to and from JSON -using the serialization API, using the derived serialization code. - -```rust -extern crate serialize; -use serialize::{json, Encodable, Decodable}; - - #[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl. - pub struct TestStruct1 { - data_int: u8, - data_str: ~str, - data_vector: ~[u8], - } - -// To serialize use the `json::str_encode` to encode an object in a string. -// It calls the generated `Encodable` impl. -fn main() { - let to_encode_object = TestStruct1 - {data_int: 1, data_str:~"toto", data_vector:~[2,3,4,5]}; - let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object); - - // To deserialize use the `json::from_str` and `json::Decoder` - - let json_object = json::from_str(encoded_str); - let mut decoder = json::Decoder::new(json_object.unwrap()); - let decoded1: TestStruct1 = Decodable::decode(&mut decoder); // create the final object -} -``` - -## Using `ToJson` - -This example use the ToJson impl to deserialize the JSON string. -Example of `ToJson` trait implementation for TestStruct1. - -```rust -extern crate serialize; -extern crate collections; - -use serialize::json::ToJson; -use serialize::{json, Encodable, Decodable}; -use collections::TreeMap; - -#[deriving(Decodable, Encodable)] // generate Decodable, Encodable impl. -pub struct TestStruct1 { - data_int: u8, - data_str: ~str, - data_vector: ~[u8], -} - -impl ToJson for TestStruct1 { - fn to_json( &self ) -> json::Json { - let mut d = ~TreeMap::new(); - d.insert(~"data_int", self.data_int.to_json()); - d.insert(~"data_str", self.data_str.to_json()); - d.insert(~"data_vector", self.data_vector.to_json()); - json::Object(d) - } -} - -fn main() { - // Serialization using our impl of to_json - - let test2: TestStruct1 = TestStruct1 {data_int: 1, data_str:~"toto", data_vector:~[2,3,4,5]}; - let tjson: json::Json = test2.to_json(); - let json_str: ~str = tjson.to_str(); - - // Deserialize like before. - - let mut decoder = json::Decoder::new(json::from_str(json_str).unwrap()); - // create the final object - let decoded2: TestStruct1 = Decodable::decode(&mut decoder); -} -``` - -*/ - -use std::char; -use std::f64; -use collections::HashMap; -use std::io; -use std::io::MemWriter; -use std::num; -use std::str; -use std::fmt; - -use Encodable; -use collections::TreeMap; - -macro_rules! try( ($e:expr) => ( - match $e { Ok(e) => e, Err(e) => { self.error = Err(e); return } } -) ) - -/// Represents a json value -#[deriving(Clone, Eq)] -pub enum Json { - Number(f64), - String(~str), - Boolean(bool), - List(List), - Object(~Object), - Null, -} - -pub type List = ~[Json]; -pub type Object = TreeMap<~str, Json>; - -#[deriving(Eq)] -/// If an error occurs while parsing some JSON, this is the structure which is -/// returned -pub struct Error { - /// The line number at which the error occurred - priv line: uint, - /// The column number at which the error occurred - priv col: uint, - /// A message describing the type of the error - priv msg: ~str, -} - -fn io_error_to_error(io: io::IoError) -> Error { - Error { - line: 0, - col: 0, - msg: format!("io error: {}", io) - } -} - -fn escape_str(s: &str) -> ~str { - let mut escaped = ~"\""; - for c in s.chars() { - match c { - '"' => escaped.push_str("\\\""), - '\\' => escaped.push_str("\\\\"), - '\x08' => escaped.push_str("\\b"), - '\x0c' => escaped.push_str("\\f"), - '\n' => escaped.push_str("\\n"), - '\r' => escaped.push_str("\\r"), - '\t' => escaped.push_str("\\t"), - _ => escaped.push_char(c), - } - }; - - escaped.push_char('"'); - - escaped -} - -fn spaces(n: uint) -> ~str { - let mut ss = ~""; - for _ in range(0, n) { ss.push_str(" "); } - return ss; -} - -/// A structure for implementing serialization to JSON. -pub struct Encoder<'a> { - priv wr: &'a mut io::Writer, - priv error: io::IoResult<()>, -} - -impl<'a> Encoder<'a> { - /// Creates a new JSON encoder whose output will be written to the writer - /// specified. - pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> { - Encoder { wr: wr, error: Ok(()) } - } - - /// Encode the specified struct into a json [u8] - pub fn buffer_encode>>(to_encode_object: &T) -> ~[u8] { - //Serialize the object in a string using a writer - let mut m = MemWriter::new(); - { - let mut encoder = Encoder::new(&mut m as &mut io::Writer); - to_encode_object.encode(&mut encoder); - } - m.unwrap() - } - - /// Encode the specified struct into a json str - pub fn str_encode>>(to_encode_object: &T) -> ~str { - let buff:~[u8] = Encoder::buffer_encode(to_encode_object); - str::from_utf8_owned(buff).unwrap() - } -} - -impl<'a> ::Encoder for Encoder<'a> { - fn emit_nil(&mut self) { try!(write!(self.wr, "null")) } - - fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); } - fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); } - fn emit_u32(&mut self, v: u32) { self.emit_f64(v as f64); } - fn emit_u16(&mut self, v: u16) { self.emit_f64(v as f64); } - fn emit_u8(&mut self, v: u8) { self.emit_f64(v as f64); } - - fn emit_int(&mut self, v: int) { self.emit_f64(v as f64); } - fn emit_i64(&mut self, v: i64) { self.emit_f64(v as f64); } - fn emit_i32(&mut self, v: i32) { self.emit_f64(v as f64); } - fn emit_i16(&mut self, v: i16) { self.emit_f64(v as f64); } - fn emit_i8(&mut self, v: i8) { self.emit_f64(v as f64); } - - fn emit_bool(&mut self, v: bool) { - if v { - try!(write!(self.wr, "true")); - } else { - try!(write!(self.wr, "false")); - } - } - - fn emit_f64(&mut self, v: f64) { - try!(write!(self.wr, "{}", f64::to_str_digits(v, 6u))) - } - fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); } - - fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) } - fn emit_str(&mut self, v: &str) { - try!(write!(self.wr, "{}", escape_str(v))) - } - - fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>|) { f(self) } - - fn emit_enum_variant(&mut self, - name: &str, - _id: uint, - cnt: uint, - f: |&mut Encoder<'a>|) { - // enums are encoded as strings or objects - // Bunny => "Bunny" - // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]} - if cnt == 0 { - try!(write!(self.wr, "{}", escape_str(name))); - } else { - try!(write!(self.wr, "\\{\"variant\":")); - try!(write!(self.wr, "{}", escape_str(name))); - try!(write!(self.wr, ",\"fields\":[")); - f(self); - try!(write!(self.wr, "]\\}")); - } - } - - fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) { - if idx != 0 { - try!(write!(self.wr, ",")); - } - f(self); - } - - fn emit_enum_struct_variant(&mut self, - name: &str, - id: uint, - cnt: uint, - f: |&mut Encoder<'a>|) { - self.emit_enum_variant(name, id, cnt, f) - } - - fn emit_enum_struct_variant_field(&mut self, - _: &str, - idx: uint, - f: |&mut Encoder<'a>|) { - self.emit_enum_variant_arg(idx, f) - } - - fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder<'a>|) { - try!(write!(self.wr, r"\{")); - f(self); - try!(write!(self.wr, r"\}")); - } - - fn emit_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut Encoder<'a>|) { - if idx != 0 { try!(write!(self.wr, ",")) } - try!(write!(self.wr, "{}:", escape_str(name))); - f(self); - } - - fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) { - self.emit_seq(len, f) - } - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) { - self.emit_seq_elt(idx, f) - } - - fn emit_tuple_struct(&mut self, - _name: &str, - len: uint, - f: |&mut Encoder<'a>|) { - self.emit_seq(len, f) - } - fn emit_tuple_struct_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) { - self.emit_seq_elt(idx, f) - } - - fn emit_option(&mut self, f: |&mut Encoder<'a>|) { f(self); } - fn emit_option_none(&mut self) { self.emit_nil(); } - fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) { f(self); } - - fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>|) { - try!(write!(self.wr, "[")); - f(self); - try!(write!(self.wr, "]")); - } - - fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>|) { - if idx != 0 { - try!(write!(self.wr, ",")); - } - f(self) - } - - fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>|) { - try!(write!(self.wr, r"\{")); - f(self); - try!(write!(self.wr, r"\}")); - } - - fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder<'a>|) { - use std::str::from_utf8; - if idx != 0 { try!(write!(self.wr, ",")) } - // ref #12967, make sure to wrap a key in double quotes, - // in the event that its of a type that omits them (eg numbers) - let mut buf = MemWriter::new(); - let mut check_encoder = Encoder::new(&mut buf); - f(&mut check_encoder); - let buf = buf.unwrap(); - let out = from_utf8(buf).unwrap(); - let needs_wrapping = out.char_at(0) != '"' && - out.char_at_reverse(out.len()) != '"'; - if needs_wrapping { try!(write!(self.wr, "\"")); } - f(self); - if needs_wrapping { try!(write!(self.wr, "\"")); } - } - - fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) { - try!(write!(self.wr, ":")); - f(self) - } -} - -/// Another encoder for JSON, but prints out human-readable JSON instead of -/// compact data -pub struct PrettyEncoder<'a> { - priv wr: &'a mut io::Writer, - priv indent: uint, - priv error: io::IoResult<()>, -} - -impl<'a> PrettyEncoder<'a> { - /// Creates a new encoder whose output will be written to the specified writer - pub fn new<'a>(wr: &'a mut io::Writer) -> PrettyEncoder<'a> { - PrettyEncoder { - wr: wr, - indent: 0, - error: Ok(()) - } - } -} - -impl<'a> ::Encoder for PrettyEncoder<'a> { - fn emit_nil(&mut self) { try!(write!(self.wr, "null")); } - - fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); } - fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); } - fn emit_u32(&mut self, v: u32) { self.emit_f64(v as f64); } - fn emit_u16(&mut self, v: u16) { self.emit_f64(v as f64); } - fn emit_u8(&mut self, v: u8) { self.emit_f64(v as f64); } - - fn emit_int(&mut self, v: int) { self.emit_f64(v as f64); } - fn emit_i64(&mut self, v: i64) { self.emit_f64(v as f64); } - fn emit_i32(&mut self, v: i32) { self.emit_f64(v as f64); } - fn emit_i16(&mut self, v: i16) { self.emit_f64(v as f64); } - fn emit_i8(&mut self, v: i8) { self.emit_f64(v as f64); } - - fn emit_bool(&mut self, v: bool) { - if v { - try!(write!(self.wr, "true")); - } else { - try!(write!(self.wr, "false")); - } - } - - fn emit_f64(&mut self, v: f64) { - try!(write!(self.wr, "{}", f64::to_str_digits(v, 6u))); - } - fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); } - - fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) } - fn emit_str(&mut self, v: &str) { - try!(write!(self.wr, "{}", escape_str(v))); - } - - fn emit_enum(&mut self, _name: &str, f: |&mut PrettyEncoder<'a>|) { - f(self) - } - - fn emit_enum_variant(&mut self, - name: &str, - _: uint, - cnt: uint, - f: |&mut PrettyEncoder<'a>|) { - if cnt == 0 { - try!(write!(self.wr, "{}", escape_str(name))); - } else { - self.indent += 2; - try!(write!(self.wr, "[\n{}{},\n", spaces(self.indent), - escape_str(name))); - f(self); - self.indent -= 2; - try!(write!(self.wr, "\n{}]", spaces(self.indent))); - } - } - - fn emit_enum_variant_arg(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>|) { - if idx != 0 { - try!(write!(self.wr, ",\n")); - } - try!(write!(self.wr, "{}", spaces(self.indent))); - f(self) - } - - fn emit_enum_struct_variant(&mut self, - name: &str, - id: uint, - cnt: uint, - f: |&mut PrettyEncoder<'a>|) { - self.emit_enum_variant(name, id, cnt, f) - } - - fn emit_enum_struct_variant_field(&mut self, - _: &str, - idx: uint, - f: |&mut PrettyEncoder<'a>|) { - self.emit_enum_variant_arg(idx, f) - } - - - fn emit_struct(&mut self, - _: &str, - len: uint, - f: |&mut PrettyEncoder<'a>|) { - if len == 0 { - try!(write!(self.wr, "\\{\\}")); - } else { - try!(write!(self.wr, "\\{")); - self.indent += 2; - f(self); - self.indent -= 2; - try!(write!(self.wr, "\n{}\\}", spaces(self.indent))); - } - } - - fn emit_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut PrettyEncoder<'a>|) { - if idx == 0 { - try!(write!(self.wr, "\n")); - } else { - try!(write!(self.wr, ",\n")); - } - try!(write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name))); - f(self); - } - - fn emit_tuple(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) { - self.emit_seq(len, f) - } - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) { - self.emit_seq_elt(idx, f) - } - - fn emit_tuple_struct(&mut self, - _: &str, - len: uint, - f: |&mut PrettyEncoder<'a>|) { - self.emit_seq(len, f) - } - fn emit_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut PrettyEncoder<'a>|) { - self.emit_seq_elt(idx, f) - } - - fn emit_option(&mut self, f: |&mut PrettyEncoder<'a>|) { f(self); } - fn emit_option_none(&mut self) { self.emit_nil(); } - fn emit_option_some(&mut self, f: |&mut PrettyEncoder<'a>|) { f(self); } - - fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) { - if len == 0 { - try!(write!(self.wr, "[]")); - } else { - try!(write!(self.wr, "[")); - self.indent += 2; - f(self); - self.indent -= 2; - try!(write!(self.wr, "\n{}]", spaces(self.indent))); - } - } - - fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) { - if idx == 0 { - try!(write!(self.wr, "\n")); - } else { - try!(write!(self.wr, ",\n")); - } - try!(write!(self.wr, "{}", spaces(self.indent))); - f(self) - } - - fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) { - if len == 0 { - try!(write!(self.wr, "\\{\\}")); - } else { - try!(write!(self.wr, "\\{")); - self.indent += 2; - f(self); - self.indent -= 2; - try!(write!(self.wr, "\n{}\\}", spaces(self.indent))); - } - } - - fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) { - use std::str::from_utf8; - if idx == 0 { - try!(write!(self.wr, "\n")); - } else { - try!(write!(self.wr, ",\n")); - } - try!(write!(self.wr, "{}", spaces(self.indent))); - // ref #12967, make sure to wrap a key in double quotes, - // in the event that its of a type that omits them (eg numbers) - let mut buf = MemWriter::new(); - let mut check_encoder = PrettyEncoder::new(&mut buf); - f(&mut check_encoder); - let buf = buf.unwrap(); - let out = from_utf8(buf).unwrap(); - let needs_wrapping = out.char_at(0) != '"' && - out.char_at_reverse(out.len()) != '"'; - if needs_wrapping { try!(write!(self.wr, "\"")); } - f(self); - if needs_wrapping { try!(write!(self.wr, "\"")); } - } - - fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder<'a>|) { - try!(write!(self.wr, ": ")); - f(self); - } -} - -impl Encodable for Json { - fn encode(&self, e: &mut E) { - match *self { - Number(v) => v.encode(e), - String(ref v) => v.encode(e), - Boolean(v) => v.encode(e), - List(ref v) => v.encode(e), - Object(ref v) => v.encode(e), - Null => e.emit_nil(), - } - } -} - -impl Json { - /// Encodes a json value into a io::writer. Uses a single line. - pub fn to_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> { - let mut encoder = Encoder::new(wr); - self.encode(&mut encoder); - encoder.error - } - - /// Encodes a json value into a io::writer. - /// Pretty-prints in a more readable format. - pub fn to_pretty_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> { - let mut encoder = PrettyEncoder::new(wr); - self.encode(&mut encoder); - encoder.error - } - - /// Encodes a json value into a string - pub fn to_pretty_str(&self) -> ~str { - let mut s = MemWriter::new(); - self.to_pretty_writer(&mut s as &mut io::Writer).unwrap(); - str::from_utf8_owned(s.unwrap()).unwrap() - } - - /// If the Json value is an Object, returns the value associated with the provided key. - /// Otherwise, returns None. - pub fn find<'a>(&'a self, key: &~str) -> Option<&'a Json>{ - match self { - &Object(ref map) => map.find(key), - _ => None - } - } - - /// Attempts to get a nested Json Object for each key in `keys`. - /// If any key is found not to exist, find_path will return None. - /// Otherwise, it will return the Json value associated with the final key. - pub fn find_path<'a>(&'a self, keys: &[&~str]) -> Option<&'a Json>{ - let mut target = self; - for key in keys.iter() { - match target.find(*key) { - Some(t) => { target = t; }, - None => return None - } - } - Some(target) - } - - /// If the Json value is an Object, performs a depth-first search until - /// a value associated with the provided key is found. If no value is found - /// or the Json value is not an Object, returns None. - pub fn search<'a>(&'a self, key: &~str) -> Option<&'a Json> { - match self { - &Object(ref map) => { - match map.find(key) { - Some(json_value) => Some(json_value), - None => { - let mut value : Option<&'a Json> = None; - for (_, v) in map.iter() { - value = v.search(key); - if value.is_some() { - break; - } - } - value - } - } - }, - _ => None - } - } - - /// Returns true if the Json value is an Object. Returns false otherwise. - pub fn is_object<'a>(&'a self) -> bool { - self.as_object().is_some() - } - - /// If the Json value is an Object, returns the associated TreeMap. - /// Returns None otherwise. - pub fn as_object<'a>(&'a self) -> Option<&'a Object> { - match self { - &Object(ref map) => Some(&**map), - _ => None - } - } - - /// Returns true if the Json value is a List. Returns false otherwise. - pub fn is_list<'a>(&'a self) -> bool { - self.as_list().is_some() - } - - /// If the Json value is a List, returns the associated vector. - /// Returns None otherwise. - pub fn as_list<'a>(&'a self) -> Option<&'a List> { - match self { - &List(ref list) => Some(&*list), - _ => None - } - } - - /// Returns true if the Json value is a String. Returns false otherwise. - pub fn is_string<'a>(&'a self) -> bool { - self.as_string().is_some() - } - - /// If the Json value is a String, returns the associated str. - /// Returns None otherwise. - pub fn as_string<'a>(&'a self) -> Option<&'a str> { - match *self { - String(ref s) => Some(s.as_slice()), - _ => None - } - } - - /// Returns true if the Json value is a Number. Returns false otherwise. - pub fn is_number(&self) -> bool { - self.as_number().is_some() - } - - /// If the Json value is a Number, returns the associated f64. - /// Returns None otherwise. - pub fn as_number(&self) -> Option { - match self { - &Number(n) => Some(n), - _ => None - } - } - - /// Returns true if the Json value is a Boolean. Returns false otherwise. - pub fn is_boolean(&self) -> bool { - self.as_boolean().is_some() - } - - /// If the Json value is a Boolean, returns the associated bool. - /// Returns None otherwise. - pub fn as_boolean(&self) -> Option { - match self { - &Boolean(b) => Some(b), - _ => None - } - } - - /// Returns true if the Json value is a Null. Returns false otherwise. - pub fn is_null(&self) -> bool { - self.as_null().is_some() - } - - /// If the Json value is a Null, returns (). - /// Returns None otherwise. - pub fn as_null(&self) -> Option<()> { - match self { - &Null => Some(()), - _ => None - } - } -} - -pub struct Parser { - priv rdr: T, - priv ch: Option, - priv line: uint, - priv col: uint, -} - -impl> Parser { - /// Decode a json value from an Iterator - pub fn new(rdr: T) -> Parser { - let mut p = Parser { - rdr: rdr, - ch: Some('\x00'), - line: 1, - col: 0, - }; - p.bump(); - p - } -} - -impl> Parser { - pub fn parse(&mut self) -> Result { - match self.parse_value() { - Ok(value) => { - // Skip trailing whitespaces. - self.parse_whitespace(); - // Make sure there is no trailing characters. - if self.eof() { - Ok(value) - } else { - self.error(~"trailing characters") - } - } - Err(e) => Err(e) - } - } -} - -impl> Parser { - fn eof(&self) -> bool { self.ch.is_none() } - fn ch_or_null(&self) -> char { self.ch.unwrap_or('\x00') } - fn bump(&mut self) { - self.ch = self.rdr.next(); - - if self.ch_is('\n') { - self.line += 1u; - self.col = 1u; - } else { - self.col += 1u; - } - } - - fn next_char(&mut self) -> Option { - self.bump(); - self.ch - } - fn ch_is(&self, c: char) -> bool { - self.ch == Some(c) - } - - fn error(&self, msg: ~str) -> Result { - Err(Error { line: self.line, col: self.col, msg: msg }) - } - - fn parse_value(&mut self) -> Result { - self.parse_whitespace(); - - if self.eof() { return self.error(~"EOF while parsing value"); } - - match self.ch_or_null() { - 'n' => self.parse_ident("ull", Null), - 't' => self.parse_ident("rue", Boolean(true)), - 'f' => self.parse_ident("alse", Boolean(false)), - '0' .. '9' | '-' => self.parse_number(), - '"' => { - match self.parse_str() { - Ok(s) => Ok(String(s)), - Err(e) => Err(e), - } - }, - '[' => self.parse_list(), - '{' => self.parse_object(), - _ => self.error(~"invalid syntax"), - } - } - - fn parse_whitespace(&mut self) { - while self.ch_is(' ') || - self.ch_is('\n') || - self.ch_is('\t') || - self.ch_is('\r') { self.bump(); } - } - - fn parse_ident(&mut self, ident: &str, value: Json) -> Result { - if ident.chars().all(|c| Some(c) == self.next_char()) { - self.bump(); - Ok(value) - } else { - self.error(~"invalid syntax") - } - } - - fn parse_number(&mut self) -> Result { - let mut neg = 1.0; - - if self.ch_is('-') { - self.bump(); - neg = -1.0; - } - - let mut res = match self.parse_integer() { - Ok(res) => res, - Err(e) => return Err(e) - }; - - if self.ch_is('.') { - match self.parse_decimal(res) { - Ok(r) => res = r, - Err(e) => return Err(e) - } - } - - if self.ch_is('e') || self.ch_is('E') { - match self.parse_exponent(res) { - Ok(r) => res = r, - Err(e) => return Err(e) - } - } - - Ok(Number(neg * res)) - } - - fn parse_integer(&mut self) -> Result { - let mut res = 0.0; - - match self.ch_or_null() { - '0' => { - self.bump(); - - // There can be only one leading '0'. - match self.ch_or_null() { - '0' .. '9' => return self.error(~"invalid number"), - _ => () - } - }, - '1' .. '9' => { - while !self.eof() { - match self.ch_or_null() { - c @ '0' .. '9' => { - res *= 10.0; - res += ((c as int) - ('0' as int)) as f64; - - self.bump(); - } - _ => break, - } - } - } - _ => return self.error(~"invalid number"), - } - Ok(res) - } - - fn parse_decimal(&mut self, res: f64) -> Result { - self.bump(); - - // Make sure a digit follows the decimal place. - match self.ch_or_null() { - '0' .. '9' => (), - _ => return self.error(~"invalid number") - } - - let mut res = res; - let mut dec = 1.0; - while !self.eof() { - match self.ch_or_null() { - c @ '0' .. '9' => { - dec /= 10.0; - res += (((c as int) - ('0' as int)) as f64) * dec; - - self.bump(); - } - _ => break, - } - } - - Ok(res) - } - - fn parse_exponent(&mut self, mut res: f64) -> Result { - self.bump(); - - let mut exp = 0u; - let mut neg_exp = false; - - if self.ch_is('+') { - self.bump(); - } else if self.ch_is('-') { - self.bump(); - neg_exp = true; - } - - // Make sure a digit follows the exponent place. - match self.ch_or_null() { - '0' .. '9' => (), - _ => return self.error(~"invalid number") - } - while !self.eof() { - match self.ch_or_null() { - c @ '0' .. '9' => { - exp *= 10; - exp += (c as uint) - ('0' as uint); - - self.bump(); - } - _ => break - } - } - - let exp: f64 = num::pow(10u as f64, exp); - if neg_exp { - res /= exp; - } else { - res *= exp; - } - - Ok(res) - } - - fn parse_str(&mut self) -> Result<~str, Error> { - let mut escape = false; - let mut res = ~""; - - loop { - self.bump(); - if self.eof() { - return self.error(~"EOF while parsing string"); - } - - if escape { - match self.ch_or_null() { - '"' => res.push_char('"'), - '\\' => res.push_char('\\'), - '/' => res.push_char('/'), - 'b' => res.push_char('\x08'), - 'f' => res.push_char('\x0c'), - 'n' => res.push_char('\n'), - 'r' => res.push_char('\r'), - 't' => res.push_char('\t'), - 'u' => { - // Parse \u1234. - let mut i = 0u; - let mut n = 0u; - while i < 4u && !self.eof() { - self.bump(); - n = match self.ch_or_null() { - c @ '0' .. '9' => n * 16u + (c as uint) - ('0' as uint), - 'a' | 'A' => n * 16u + 10u, - 'b' | 'B' => n * 16u + 11u, - 'c' | 'C' => n * 16u + 12u, - 'd' | 'D' => n * 16u + 13u, - 'e' | 'E' => n * 16u + 14u, - 'f' | 'F' => n * 16u + 15u, - _ => return self.error( - ~"invalid \\u escape (unrecognized hex)") - }; - - i += 1u; - } - - // Error out if we didn't parse 4 digits. - if i != 4u { - return self.error( - ~"invalid \\u escape (not four digits)"); - } - - res.push_char(char::from_u32(n as u32).unwrap()); - } - _ => return self.error(~"invalid escape"), - } - escape = false; - } else if self.ch_is('\\') { - escape = true; - } else { - match self.ch { - Some('"') => { self.bump(); return Ok(res); }, - Some(c) => res.push_char(c), - None => unreachable!() - } - } - } - } - - fn parse_list(&mut self) -> Result { - self.bump(); - self.parse_whitespace(); - - let mut values = ~[]; - - if self.ch_is(']') { - self.bump(); - return Ok(List(values)); - } - - loop { - match self.parse_value() { - Ok(v) => values.push(v), - Err(e) => return Err(e) - } - - self.parse_whitespace(); - if self.eof() { - return self.error(~"EOF while parsing list"); - } - - if self.ch_is(',') { - self.bump(); - } else if self.ch_is(']') { - self.bump(); - return Ok(List(values)); - } else { - return self.error(~"expected `,` or `]`") - } - }; - } - - fn parse_object(&mut self) -> Result { - self.bump(); - self.parse_whitespace(); - - let mut values = ~TreeMap::new(); - - if self.ch_is('}') { - self.bump(); - return Ok(Object(values)); - } - - while !self.eof() { - self.parse_whitespace(); - - if !self.ch_is('"') { - return self.error(~"key must be a string"); - } - - let key = match self.parse_str() { - Ok(key) => key, - Err(e) => return Err(e) - }; - - self.parse_whitespace(); - - if !self.ch_is(':') { - if self.eof() { break; } - return self.error(~"expected `:`"); - } - self.bump(); - - match self.parse_value() { - Ok(value) => { values.insert(key, value); } - Err(e) => return Err(e) - } - self.parse_whitespace(); - - match self.ch_or_null() { - ',' => self.bump(), - '}' => { self.bump(); return Ok(Object(values)); }, - _ => { - if self.eof() { break; } - return self.error(~"expected `,` or `}`"); - } - } - } - - return self.error(~"EOF while parsing object"); - } -} - -/// Decodes a json value from an `&mut io::Reader` -pub fn from_reader(rdr: &mut io::Reader) -> Result { - let contents = match rdr.read_to_end() { - Ok(c) => c, - Err(e) => return Err(io_error_to_error(e)) - }; - let s = match str::from_utf8_owned(contents) { - Some(s) => s, - None => return Err(Error { line: 0, col: 0, msg: ~"contents not utf-8" }) - }; - let mut parser = Parser::new(s.chars()); - parser.parse() -} - -/// Decodes a json value from a string -pub fn from_str(s: &str) -> Result { - let mut parser = Parser::new(s.chars()); - parser.parse() -} - -/// A structure to decode JSON to values in rust. -pub struct Decoder { - priv stack: ~[Json], -} - -impl Decoder { - /// Creates a new decoder instance for decoding the specified JSON value. - pub fn new(json: Json) -> Decoder { - Decoder { - stack: ~[json] - } - } -} - -impl Decoder { - fn err(&self, msg: &str) -> ! { - fail!("JSON decode error: {}", msg); - } - fn missing_field(&self, field: &str, object: ~Object) -> ! { - self.err(format!("missing required '{}' field in object: {}", - field, Object(object).to_str())) - } - fn expected(&self, expected: &str, found: &Json) -> ! { - let found_s = match *found { - Null => "null", - List(..) => "list", - Object(..) => "object", - Number(..) => "number", - String(..) => "string", - Boolean(..) => "boolean" - }; - self.err(format!("expected {expct} but found {fnd}: {val}", - expct=expected, fnd=found_s, val=found.to_str())) - } -} - -impl ::Decoder for Decoder { - fn read_nil(&mut self) -> () { - debug!("read_nil"); - match self.stack.pop().unwrap() { - Null => (), - value => self.expected("null", &value) - } - } - - fn read_u64(&mut self) -> u64 { self.read_f64() as u64 } - fn read_u32(&mut self) -> u32 { self.read_f64() as u32 } - fn read_u16(&mut self) -> u16 { self.read_f64() as u16 } - fn read_u8 (&mut self) -> u8 { self.read_f64() as u8 } - fn read_uint(&mut self) -> uint { self.read_f64() as uint } - - fn read_i64(&mut self) -> i64 { self.read_f64() as i64 } - fn read_i32(&mut self) -> i32 { self.read_f64() as i32 } - fn read_i16(&mut self) -> i16 { self.read_f64() as i16 } - fn read_i8 (&mut self) -> i8 { self.read_f64() as i8 } - fn read_int(&mut self) -> int { self.read_f64() as int } - - fn read_bool(&mut self) -> bool { - debug!("read_bool"); - match self.stack.pop().unwrap() { - Boolean(b) => b, - value => self.expected("boolean", &value) - } - } - - fn read_f64(&mut self) -> f64 { - use std::from_str::FromStr; - debug!("read_f64"); - match self.stack.pop().unwrap() { - Number(f) => f, - String(s) => { - // re: #12967.. a type w/ numeric keys (ie HashMap etc) - // is going to have a string here, as per JSON spec.. - FromStr::from_str(s).unwrap() - }, - value => self.expected("number", &value) - } - } - - fn read_f32(&mut self) -> f32 { self.read_f64() as f32 } - - fn read_char(&mut self) -> char { - let s = self.read_str(); - { - let mut it = s.chars(); - match (it.next(), it.next()) { - // exactly one character - (Some(c), None) => return c, - _ => () - } - } - self.expected("single character string", &String(s)) - } - - fn read_str(&mut self) -> ~str { - debug!("read_str"); - match self.stack.pop().unwrap() { - String(s) => s, - value => self.expected("string", &value) - } - } - - fn read_enum(&mut self, name: &str, f: |&mut Decoder| -> T) -> T { - debug!("read_enum({})", name); - f(self) - } - - fn read_enum_variant(&mut self, - names: &[&str], - f: |&mut Decoder, uint| -> T) - -> T { - debug!("read_enum_variant(names={:?})", names); - let name = match self.stack.pop().unwrap() { - String(s) => s, - Object(mut o) => { - let n = match o.pop(&~"variant") { - Some(String(s)) => s, - Some(val) => self.expected("string", &val), - None => self.missing_field("variant", o) - }; - match o.pop(&~"fields") { - Some(List(l)) => { - for field in l.move_rev_iter() { - self.stack.push(field.clone()); - } - }, - Some(val) => self.expected("list", &val), - None => { - // re-insert the variant field so we're - // printing the "whole" struct in the error - // message... ick. - o.insert(~"variant", String(n)); - self.missing_field("fields", o); - } - } - n - } - json => self.expected("string or object", &json) - }; - let idx = match names.iter().position(|n| str::eq_slice(*n, name)) { - Some(idx) => idx, - None => self.err(format!("unknown variant name: {}", name)) - }; - f(self, idx) - } - - fn read_enum_variant_arg(&mut self, idx: uint, f: |&mut Decoder| -> T) - -> T { - debug!("read_enum_variant_arg(idx={})", idx); - f(self) - } - - fn read_enum_struct_variant(&mut self, - names: &[&str], - f: |&mut Decoder, uint| -> T) - -> T { - debug!("read_enum_struct_variant(names={:?})", names); - self.read_enum_variant(names, f) - } - - - fn read_enum_struct_variant_field(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder| -> T) - -> T { - debug!("read_enum_struct_variant_field(name={}, idx={})", name, idx); - self.read_enum_variant_arg(idx, f) - } - - fn read_struct(&mut self, - name: &str, - len: uint, - f: |&mut Decoder| -> T) - -> T { - debug!("read_struct(name={}, len={})", name, len); - let value = f(self); - self.stack.pop().unwrap(); - value - } - - fn read_struct_field(&mut self, - name: &str, - idx: uint, - f: |&mut Decoder| -> T) - -> T { - debug!("read_struct_field(name={}, idx={})", name, idx); - match self.stack.pop().unwrap() { - Object(mut obj) => { - let value = match obj.pop(&name.to_owned()) { - None => self.missing_field(name, obj), - Some(json) => { - self.stack.push(json); - f(self) - } - }; - self.stack.push(Object(obj)); - value - } - value => self.expected("object", &value) - } - } - - fn read_tuple(&mut self, f: |&mut Decoder, uint| -> T) -> T { - debug!("read_tuple()"); - self.read_seq(f) - } - - fn read_tuple_arg(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T { - debug!("read_tuple_arg(idx={})", idx); - self.read_seq_elt(idx, f) - } - - fn read_tuple_struct(&mut self, - name: &str, - f: |&mut Decoder, uint| -> T) - -> T { - debug!("read_tuple_struct(name={})", name); - self.read_tuple(f) - } - - fn read_tuple_struct_arg(&mut self, - idx: uint, - f: |&mut Decoder| -> T) - -> T { - debug!("read_tuple_struct_arg(idx={})", idx); - self.read_tuple_arg(idx, f) - } - - fn read_option(&mut self, f: |&mut Decoder, bool| -> T) -> T { - match self.stack.pop().unwrap() { - Null => f(self, false), - value => { self.stack.push(value); f(self, true) } - } - } - - fn read_seq(&mut self, f: |&mut Decoder, uint| -> T) -> T { - debug!("read_seq()"); - let len = match self.stack.pop().unwrap() { - List(list) => { - let len = list.len(); - for v in list.move_rev_iter() { - self.stack.push(v); - } - len - } - value => self.expected("list", &value) - }; - f(self, len) - } - - fn read_seq_elt(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T { - debug!("read_seq_elt(idx={})", idx); - f(self) - } - - fn read_map(&mut self, f: |&mut Decoder, uint| -> T) -> T { - debug!("read_map()"); - let len = match self.stack.pop().unwrap() { - Object(obj) => { - let len = obj.len(); - for (key, value) in obj.move_iter() { - self.stack.push(value); - self.stack.push(String(key)); - } - len - } - value => self.expected("object", &value) - }; - f(self, len) - } - - fn read_map_elt_key(&mut self, idx: uint, f: |&mut Decoder| -> T) - -> T { - debug!("read_map_elt_key(idx={})", idx); - f(self) - } - - fn read_map_elt_val(&mut self, idx: uint, f: |&mut Decoder| -> T) - -> T { - debug!("read_map_elt_val(idx={})", idx); - f(self) - } -} - -/// Test if two json values are less than one another -impl Ord for Json { - fn lt(&self, other: &Json) -> bool { - match *self { - Number(f0) => { - match *other { - Number(f1) => f0 < f1, - String(_) | Boolean(_) | List(_) | Object(_) | - Null => true - } - } - - String(ref s0) => { - match *other { - Number(_) => false, - String(ref s1) => s0 < s1, - Boolean(_) | List(_) | Object(_) | Null => true - } - } - - Boolean(b0) => { - match *other { - Number(_) | String(_) => false, - Boolean(b1) => b0 < b1, - List(_) | Object(_) | Null => true - } - } - - List(ref l0) => { - match *other { - Number(_) | String(_) | Boolean(_) => false, - List(ref l1) => (*l0) < (*l1), - Object(_) | Null => true - } - } - - Object(ref d0) => { - match *other { - Number(_) | String(_) | Boolean(_) | List(_) => false, - Object(ref d1) => d0 < d1, - Null => true - } - } - - Null => { - match *other { - Number(_) | String(_) | Boolean(_) | List(_) | - Object(_) => - false, - Null => true - } - } - } - } -} - -/// A trait for converting values to JSON -pub trait ToJson { - /// Converts the value of `self` to an instance of JSON - fn to_json(&self) -> Json; -} - -impl ToJson for Json { - fn to_json(&self) -> Json { (*self).clone() } -} - -impl ToJson for int { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for i8 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for i16 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for i32 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for i64 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for uint { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for u8 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for u16 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for u32 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for u64 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for f32 { - fn to_json(&self) -> Json { Number(*self as f64) } -} - -impl ToJson for f64 { - fn to_json(&self) -> Json { Number(*self) } -} - -impl ToJson for () { - fn to_json(&self) -> Json { Null } -} - -impl ToJson for bool { - fn to_json(&self) -> Json { Boolean(*self) } -} - -impl ToJson for ~str { - fn to_json(&self) -> Json { String((*self).clone()) } -} - -impl ToJson for (A, B) { - fn to_json(&self) -> Json { - match *self { - (ref a, ref b) => { - List(~[a.to_json(), b.to_json()]) - } - } - } -} - -impl ToJson for (A, B, C) { - fn to_json(&self) -> Json { - match *self { - (ref a, ref b, ref c) => { - List(~[a.to_json(), b.to_json(), c.to_json()]) - } - } - } -} - -impl ToJson for ~[A] { - fn to_json(&self) -> Json { List(self.map(|elt| elt.to_json())) } -} - -impl ToJson for TreeMap<~str, A> { - fn to_json(&self) -> Json { - let mut d = TreeMap::new(); - for (key, value) in self.iter() { - d.insert((*key).clone(), value.to_json()); - } - Object(~d) - } -} - -impl ToJson for HashMap<~str, A> { - fn to_json(&self) -> Json { - let mut d = TreeMap::new(); - for (key, value) in self.iter() { - d.insert((*key).clone(), value.to_json()); - } - Object(~d) - } -} - -impl ToJson for Option { - fn to_json(&self) -> Json { - match *self { - None => Null, - Some(ref value) => value.to_json() - } - } -} - -impl fmt::Show for Json { - /// Encodes a json value into a string - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.to_writer(f.buf) - } -} - -impl fmt::Show for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f.buf, "{}:{}: {}", self.line, self.col, self.msg) - } -} - -#[cfg(test)] -mod tests { - use {Encodable, Decodable}; - use super::{Encoder, Decoder, Error, Boolean, Number, List, String, Null, - PrettyEncoder, Object, Json, from_str}; - use std::io; - use collections::TreeMap; - - #[deriving(Eq, Encodable, Decodable, Show)] - enum Animal { - Dog, - Frog(~str, int) - } - - #[deriving(Eq, Encodable, Decodable, Show)] - struct Inner { - a: (), - b: uint, - c: ~[~str], - } - - #[deriving(Eq, Encodable, Decodable, Show)] - struct Outer { - inner: ~[Inner], - } - - fn mk_object(items: &[(~str, Json)]) -> Json { - let mut d = ~TreeMap::new(); - - for item in items.iter() { - match *item { - (ref key, ref value) => { d.insert((*key).clone(), (*value).clone()); }, - } - }; - - Object(d) - } - - #[test] - fn test_write_null() { - assert_eq!(Null.to_str(), ~"null"); - assert_eq!(Null.to_pretty_str(), ~"null"); - } - - - #[test] - fn test_write_number() { - assert_eq!(Number(3.0).to_str(), ~"3"); - assert_eq!(Number(3.0).to_pretty_str(), ~"3"); - - assert_eq!(Number(3.1).to_str(), ~"3.1"); - assert_eq!(Number(3.1).to_pretty_str(), ~"3.1"); - - assert_eq!(Number(-1.5).to_str(), ~"-1.5"); - assert_eq!(Number(-1.5).to_pretty_str(), ~"-1.5"); - - assert_eq!(Number(0.5).to_str(), ~"0.5"); - assert_eq!(Number(0.5).to_pretty_str(), ~"0.5"); - } - - #[test] - fn test_write_str() { - assert_eq!(String(~"").to_str(), ~"\"\""); - assert_eq!(String(~"").to_pretty_str(), ~"\"\""); - - assert_eq!(String(~"foo").to_str(), ~"\"foo\""); - assert_eq!(String(~"foo").to_pretty_str(), ~"\"foo\""); - } - - #[test] - fn test_write_bool() { - assert_eq!(Boolean(true).to_str(), ~"true"); - assert_eq!(Boolean(true).to_pretty_str(), ~"true"); - - assert_eq!(Boolean(false).to_str(), ~"false"); - assert_eq!(Boolean(false).to_pretty_str(), ~"false"); - } - - #[test] - fn test_write_list() { - assert_eq!(List(~[]).to_str(), ~"[]"); - assert_eq!(List(~[]).to_pretty_str(), ~"[]"); - - assert_eq!(List(~[Boolean(true)]).to_str(), ~"[true]"); - assert_eq!( - List(~[Boolean(true)]).to_pretty_str(), - ~"\ - [\n \ - true\n\ - ]" - ); - - let long_test_list = List(~[ - Boolean(false), - Null, - List(~[String(~"foo\nbar"), Number(3.5)])]); - - assert_eq!(long_test_list.to_str(), - ~"[false,null,[\"foo\\nbar\",3.5]]"); - assert_eq!( - long_test_list.to_pretty_str(), - ~"\ - [\n \ - false,\n \ - null,\n \ - [\n \ - \"foo\\nbar\",\n \ - 3.5\n \ - ]\n\ - ]" - ); - } - - #[test] - fn test_write_object() { - assert_eq!(mk_object([]).to_str(), ~"{}"); - assert_eq!(mk_object([]).to_pretty_str(), ~"{}"); - - assert_eq!( - mk_object([(~"a", Boolean(true))]).to_str(), - ~"{\"a\":true}" - ); - assert_eq!( - mk_object([(~"a", Boolean(true))]).to_pretty_str(), - ~"\ - {\n \ - \"a\": true\n\ - }" - ); - - let complex_obj = mk_object([ - (~"b", List(~[ - mk_object([(~"c", String(~"\x0c\r"))]), - mk_object([(~"d", String(~""))]) - ])) - ]); - - assert_eq!( - complex_obj.to_str(), - ~"{\ - \"b\":[\ - {\"c\":\"\\f\\r\"},\ - {\"d\":\"\"}\ - ]\ - }" - ); - assert_eq!( - complex_obj.to_pretty_str(), - ~"\ - {\n \ - \"b\": [\n \ - {\n \ - \"c\": \"\\f\\r\"\n \ - },\n \ - {\n \ - \"d\": \"\"\n \ - }\n \ - ]\n\ - }" - ); - - let a = mk_object([ - (~"a", Boolean(true)), - (~"b", List(~[ - mk_object([(~"c", String(~"\x0c\r"))]), - mk_object([(~"d", String(~""))]) - ])) - ]); - - // We can't compare the strings directly because the object fields be - // printed in a different order. - assert_eq!(a.clone(), from_str(a.to_str()).unwrap()); - assert_eq!(a.clone(), from_str(a.to_pretty_str()).unwrap()); - } - - fn with_str_writer(f: |&mut io::Writer|) -> ~str { - use std::io::MemWriter; - use std::str; - - let mut m = MemWriter::new(); - f(&mut m as &mut io::Writer); - str::from_utf8_owned(m.unwrap()).unwrap() - } - - #[test] - fn test_write_enum() { - let animal = Dog; - assert_eq!( - with_str_writer(|wr| { - let mut encoder = Encoder::new(wr); - animal.encode(&mut encoder); - }), - ~"\"Dog\"" - ); - assert_eq!( - with_str_writer(|wr| { - let mut encoder = PrettyEncoder::new(wr); - animal.encode(&mut encoder); - }), - ~"\"Dog\"" - ); - - let animal = Frog(~"Henry", 349); - assert_eq!( - with_str_writer(|wr| { - let mut encoder = Encoder::new(wr); - animal.encode(&mut encoder); - }), - ~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}" - ); - assert_eq!( - with_str_writer(|wr| { - let mut encoder = PrettyEncoder::new(wr); - animal.encode(&mut encoder); - }), - ~"\ - [\n \ - \"Frog\",\n \ - \"Henry\",\n \ - 349\n\ - ]" - ); - } - - #[test] - fn test_write_some() { - let value = Some(~"jodhpurs"); - let s = with_str_writer(|wr| { - let mut encoder = Encoder::new(wr); - value.encode(&mut encoder); - }); - assert_eq!(s, ~"\"jodhpurs\""); - - let value = Some(~"jodhpurs"); - let s = with_str_writer(|wr| { - let mut encoder = PrettyEncoder::new(wr); - value.encode(&mut encoder); - }); - assert_eq!(s, ~"\"jodhpurs\""); - } - - #[test] - fn test_write_none() { - let value: Option<~str> = None; - let s = with_str_writer(|wr| { - let mut encoder = Encoder::new(wr); - value.encode(&mut encoder); - }); - assert_eq!(s, ~"null"); - - let s = with_str_writer(|wr| { - let mut encoder = Encoder::new(wr); - value.encode(&mut encoder); - }); - assert_eq!(s, ~"null"); - } - - #[test] - fn test_trailing_characters() { - assert_eq!(from_str("nulla"), - Err(Error {line: 1u, col: 5u, msg: ~"trailing characters"})); - assert_eq!(from_str("truea"), - Err(Error {line: 1u, col: 5u, msg: ~"trailing characters"})); - assert_eq!(from_str("falsea"), - Err(Error {line: 1u, col: 6u, msg: ~"trailing characters"})); - assert_eq!(from_str("1a"), - Err(Error {line: 1u, col: 2u, msg: ~"trailing characters"})); - assert_eq!(from_str("[]a"), - Err(Error {line: 1u, col: 3u, msg: ~"trailing characters"})); - assert_eq!(from_str("{}a"), - Err(Error {line: 1u, col: 3u, msg: ~"trailing characters"})); - } - - #[test] - fn test_read_identifiers() { - assert_eq!(from_str("n"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"})); - assert_eq!(from_str("nul"), - Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"})); - - assert_eq!(from_str("t"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"})); - assert_eq!(from_str("truz"), - Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"})); - - assert_eq!(from_str("f"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"})); - assert_eq!(from_str("faz"), - Err(Error {line: 1u, col: 3u, msg: ~"invalid syntax"})); - - assert_eq!(from_str("null"), Ok(Null)); - assert_eq!(from_str("true"), Ok(Boolean(true))); - assert_eq!(from_str("false"), Ok(Boolean(false))); - assert_eq!(from_str(" null "), Ok(Null)); - assert_eq!(from_str(" true "), Ok(Boolean(true))); - assert_eq!(from_str(" false "), Ok(Boolean(false))); - } - - #[test] - fn test_decode_identifiers() { - let mut decoder = Decoder::new(from_str("null").unwrap()); - let v: () = Decodable::decode(&mut decoder); - assert_eq!(v, ()); - - let mut decoder = Decoder::new(from_str("true").unwrap()); - let v: bool = Decodable::decode(&mut decoder); - assert_eq!(v, true); - - let mut decoder = Decoder::new(from_str("false").unwrap()); - let v: bool = Decodable::decode(&mut decoder); - assert_eq!(v, false); - } - - #[test] - fn test_read_number() { - assert_eq!(from_str("+"), - Err(Error {line: 1u, col: 1u, msg: ~"invalid syntax"})); - assert_eq!(from_str("."), - Err(Error {line: 1u, col: 1u, msg: ~"invalid syntax"})); - - assert_eq!(from_str("-"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid number"})); - assert_eq!(from_str("00"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid number"})); - assert_eq!(from_str("1."), - Err(Error {line: 1u, col: 3u, msg: ~"invalid number"})); - assert_eq!(from_str("1e"), - Err(Error {line: 1u, col: 3u, msg: ~"invalid number"})); - assert_eq!(from_str("1e+"), - Err(Error {line: 1u, col: 4u, msg: ~"invalid number"})); - - assert_eq!(from_str("3"), Ok(Number(3.0))); - assert_eq!(from_str("3.1"), Ok(Number(3.1))); - assert_eq!(from_str("-1.2"), Ok(Number(-1.2))); - assert_eq!(from_str("0.4"), Ok(Number(0.4))); - assert_eq!(from_str("0.4e5"), Ok(Number(0.4e5))); - assert_eq!(from_str("0.4e+15"), Ok(Number(0.4e15))); - assert_eq!(from_str("0.4e-01"), Ok(Number(0.4e-01))); - assert_eq!(from_str(" 3 "), Ok(Number(3.0))); - } - - #[test] - fn test_decode_numbers() { - let mut decoder = Decoder::new(from_str("3").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); - assert_eq!(v, 3.0); - - let mut decoder = Decoder::new(from_str("3.1").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); - assert_eq!(v, 3.1); - - let mut decoder = Decoder::new(from_str("-1.2").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); - assert_eq!(v, -1.2); - - let mut decoder = Decoder::new(from_str("0.4").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); - assert_eq!(v, 0.4); - - let mut decoder = Decoder::new(from_str("0.4e5").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); - assert_eq!(v, 0.4e5); - - let mut decoder = Decoder::new(from_str("0.4e15").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); - assert_eq!(v, 0.4e15); - - let mut decoder = Decoder::new(from_str("0.4e-01").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); - assert_eq!(v, 0.4e-01); - } - - #[test] - fn test_read_str() { - assert_eq!(from_str("\""), - Err(Error {line: 1u, col: 2u, msg: ~"EOF while parsing string" - })); - assert_eq!(from_str("\"lol"), - Err(Error {line: 1u, col: 5u, msg: ~"EOF while parsing string" - })); - - assert_eq!(from_str("\"\""), Ok(String(~""))); - assert_eq!(from_str("\"foo\""), Ok(String(~"foo"))); - assert_eq!(from_str("\"\\\"\""), Ok(String(~"\""))); - assert_eq!(from_str("\"\\b\""), Ok(String(~"\x08"))); - assert_eq!(from_str("\"\\n\""), Ok(String(~"\n"))); - assert_eq!(from_str("\"\\r\""), Ok(String(~"\r"))); - assert_eq!(from_str("\"\\t\""), Ok(String(~"\t"))); - assert_eq!(from_str(" \"foo\" "), Ok(String(~"foo"))); - assert_eq!(from_str("\"\\u12ab\""), Ok(String(~"\u12ab"))); - assert_eq!(from_str("\"\\uAB12\""), Ok(String(~"\uAB12"))); - } - - #[test] - fn test_decode_str() { - let mut decoder = Decoder::new(from_str("\"\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~""); - - let mut decoder = Decoder::new(from_str("\"foo\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~"foo"); - - let mut decoder = Decoder::new(from_str("\"\\\"\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~"\""); - - let mut decoder = Decoder::new(from_str("\"\\b\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~"\x08"); - - let mut decoder = Decoder::new(from_str("\"\\n\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~"\n"); - - let mut decoder = Decoder::new(from_str("\"\\r\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~"\r"); - - let mut decoder = Decoder::new(from_str("\"\\t\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~"\t"); - - let mut decoder = Decoder::new(from_str("\"\\u12ab\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~"\u12ab"); - - let mut decoder = Decoder::new(from_str("\"\\uAB12\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); - assert_eq!(v, ~"\uAB12"); - } - - #[test] - fn test_read_list() { - assert_eq!(from_str("["), - Err(Error {line: 1u, col: 2u, msg: ~"EOF while parsing value"})); - assert_eq!(from_str("[1"), - Err(Error {line: 1u, col: 3u, msg: ~"EOF while parsing list"})); - assert_eq!(from_str("[1,"), - Err(Error {line: 1u, col: 4u, msg: ~"EOF while parsing value"})); - assert_eq!(from_str("[1,]"), - Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"})); - assert_eq!(from_str("[6 7]"), - Err(Error {line: 1u, col: 4u, msg: ~"expected `,` or `]`"})); - - assert_eq!(from_str("[]"), Ok(List(~[]))); - assert_eq!(from_str("[ ]"), Ok(List(~[]))); - assert_eq!(from_str("[true]"), Ok(List(~[Boolean(true)]))); - assert_eq!(from_str("[ false ]"), Ok(List(~[Boolean(false)]))); - assert_eq!(from_str("[null]"), Ok(List(~[Null]))); - assert_eq!(from_str("[3, 1]"), - Ok(List(~[Number(3.0), Number(1.0)]))); - assert_eq!(from_str("\n[3, 2]\n"), - Ok(List(~[Number(3.0), Number(2.0)]))); - assert_eq!(from_str("[2, [4, 1]]"), - Ok(List(~[Number(2.0), List(~[Number(4.0), Number(1.0)])]))); - } - - #[test] - fn test_decode_list() { - let mut decoder = Decoder::new(from_str("[]").unwrap()); - let v: ~[()] = Decodable::decode(&mut decoder); - assert_eq!(v, ~[]); - - let mut decoder = Decoder::new(from_str("[null]").unwrap()); - let v: ~[()] = Decodable::decode(&mut decoder); - assert_eq!(v, ~[()]); - - let mut decoder = Decoder::new(from_str("[true]").unwrap()); - let v: ~[bool] = Decodable::decode(&mut decoder); - assert_eq!(v, ~[true]); - - let mut decoder = Decoder::new(from_str("[true]").unwrap()); - let v: ~[bool] = Decodable::decode(&mut decoder); - assert_eq!(v, ~[true]); - - let mut decoder = Decoder::new(from_str("[3, 1]").unwrap()); - let v: ~[int] = Decodable::decode(&mut decoder); - assert_eq!(v, ~[3, 1]); - - let mut decoder = Decoder::new(from_str("[[3], [1, 2]]").unwrap()); - let v: ~[~[uint]] = Decodable::decode(&mut decoder); - assert_eq!(v, ~[~[3], ~[1, 2]]); - } - - #[test] - fn test_read_object() { - assert_eq!(from_str("{"), - Err(Error { - line: 1u, - col: 2u, - msg: ~"EOF while parsing object"})); - assert_eq!(from_str("{ "), - Err(Error { - line: 1u, - col: 3u, - msg: ~"EOF while parsing object"})); - assert_eq!(from_str("{1"), - Err(Error { - line: 1u, - col: 2u, - msg: ~"key must be a string"})); - assert_eq!(from_str("{ \"a\""), - Err(Error { - line: 1u, - col: 6u, - msg: ~"EOF while parsing object"})); - assert_eq!(from_str("{\"a\""), - Err(Error { - line: 1u, - col: 5u, - msg: ~"EOF while parsing object"})); - assert_eq!(from_str("{\"a\" "), - Err(Error { - line: 1u, - col: 6u, - msg: ~"EOF while parsing object"})); - - assert_eq!(from_str("{\"a\" 1"), - Err(Error {line: 1u, col: 6u, msg: ~"expected `:`"})); - assert_eq!(from_str("{\"a\":"), - Err(Error {line: 1u, col: 6u, msg: ~"EOF while parsing value"})); - assert_eq!(from_str("{\"a\":1"), - Err(Error { - line: 1u, - col: 7u, - msg: ~"EOF while parsing object"})); - assert_eq!(from_str("{\"a\":1 1"), - Err(Error {line: 1u, col: 8u, msg: ~"expected `,` or `}`"})); - assert_eq!(from_str("{\"a\":1,"), - Err(Error { - line: 1u, - col: 8u, - msg: ~"EOF while parsing object"})); - - assert_eq!(from_str("{}").unwrap(), mk_object([])); - assert_eq!(from_str("{\"a\": 3}").unwrap(), - mk_object([(~"a", Number(3.0))])); - - assert_eq!(from_str( - "{ \"a\": null, \"b\" : true }").unwrap(), - mk_object([ - (~"a", Null), - (~"b", Boolean(true))])); - assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(), - mk_object([ - (~"a", Null), - (~"b", Boolean(true))])); - assert_eq!(from_str( - "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(), - mk_object([ - (~"a", Number(1.0)), - (~"b", List(~[Boolean(true)])) - ])); - assert_eq!(from_str( - ~"{" + - "\"a\": 1.0, " + - "\"b\": [" + - "true," + - "\"foo\\nbar\", " + - "{ \"c\": {\"d\": null} } " + - "]" + - "}").unwrap(), - mk_object([ - (~"a", Number(1.0)), - (~"b", List(~[ - Boolean(true), - String(~"foo\nbar"), - mk_object([ - (~"c", mk_object([(~"d", Null)])) - ]) - ])) - ])); - } - - #[test] - fn test_decode_struct() { - let s = ~"{ - \"inner\": [ - { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } - ] - }"; - let mut decoder = Decoder::new(from_str(s).unwrap()); - let v: Outer = Decodable::decode(&mut decoder); - assert_eq!( - v, - Outer { - inner: ~[ - Inner { a: (), b: 2, c: ~[~"abc", ~"xyz"] } - ] - } - ); - } - - #[test] - fn test_decode_option() { - let mut decoder = Decoder::new(from_str("null").unwrap()); - let value: Option<~str> = Decodable::decode(&mut decoder); - assert_eq!(value, None); - - let mut decoder = Decoder::new(from_str("\"jodhpurs\"").unwrap()); - let value: Option<~str> = Decodable::decode(&mut decoder); - assert_eq!(value, Some(~"jodhpurs")); - } - - #[test] - fn test_decode_enum() { - let mut decoder = Decoder::new(from_str("\"Dog\"").unwrap()); - let value: Animal = Decodable::decode(&mut decoder); - assert_eq!(value, Dog); - - let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"; - let mut decoder = Decoder::new(from_str(s).unwrap()); - let value: Animal = Decodable::decode(&mut decoder); - assert_eq!(value, Frog(~"Henry", 349)); - } - - #[test] - fn test_decode_map() { - let s = ~"{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\"fields\":[\"Henry\", 349]}}"; - let mut decoder = Decoder::new(from_str(s).unwrap()); - let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder); - - assert_eq!(map.pop(&~"a"), Some(Dog)); - assert_eq!(map.pop(&~"b"), Some(Frog(~"Henry", 349))); - } - - #[test] - fn test_multiline_errors() { - assert_eq!(from_str("{\n \"foo\":\n \"bar\""), - Err(Error { - line: 3u, - col: 8u, - msg: ~"EOF while parsing object"})); - } - - #[deriving(Decodable)] - struct DecodeStruct { - x: f64, - y: bool, - z: ~str, - w: ~[DecodeStruct] - } - #[deriving(Decodable)] - enum DecodeEnum { - A(f64), - B(~str) - } - fn check_err>(to_parse: &'static str, expected_error: &str) { - use std::any::AnyRefExt; - use std::task; - let res = task::try(proc() { - // either fails in `decode` (which is what we want), or - // returns Some(error_message)/None if the string was - // invalid or valid JSON. - match from_str(to_parse) { - Err(e) => Some(e.to_str()), - Ok(json) => { - let _: T = Decodable::decode(&mut Decoder::new(json)); - None - } - } - }); - match res { - Ok(Some(parse_error)) => fail!("`{}` is not valid json: {}", - to_parse, parse_error), - Ok(None) => fail!("`{}` parsed & decoded ok, expecting error `{}`", - to_parse, expected_error), - Err(e) => { - let err = e.as_ref::<~str>().unwrap(); - assert!(err.contains(expected_error), - "`{}` errored incorrectly, found `{}` expecting `{}`", - to_parse, *err, expected_error); - } - } - } - #[test] - fn test_decode_errors_struct() { - check_err::("[]", "object but found list"); - check_err::("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", - "number but found boolean"); - check_err::("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", - "boolean but found list"); - check_err::("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", - "string but found object"); - check_err::("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", - "list but found null"); - check_err::("{\"x\": 1, \"y\": true, \"z\": \"\"}", - "'w' field in object"); - } - #[test] - fn test_decode_errors_enum() { - check_err::("{}", - "'variant' field in object"); - check_err::("{\"variant\": 1}", - "string but found number"); - check_err::("{\"variant\": \"A\"}", - "'fields' field in object"); - check_err::("{\"variant\": \"A\", \"fields\": null}", - "list but found null"); - check_err::("{\"variant\": \"C\", \"fields\": []}", - "unknown variant name"); - } - - #[test] - fn test_find(){ - let json_value = from_str("{\"dog\" : \"cat\"}").unwrap(); - let found_str = json_value.find(&~"dog"); - assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == &"cat"); - } - - #[test] - fn test_find_path(){ - let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.find_path(&[&~"dog", &~"cat", &~"mouse"]); - assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == &"cheese"); - } - - #[test] - fn test_search(){ - let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.search(&~"mouse").and_then(|j| j.as_string()); - assert!(found_str.is_some()); - assert!(found_str.unwrap() == &"cheese"); - } - - #[test] - fn test_is_object(){ - let json_value = from_str("{}").unwrap(); - assert!(json_value.is_object()); - } - - #[test] - fn test_as_object(){ - let json_value = from_str("{}").unwrap(); - let json_object = json_value.as_object(); - assert!(json_object.is_some()); - } - - #[test] - fn test_is_list(){ - let json_value = from_str("[1, 2, 3]").unwrap(); - assert!(json_value.is_list()); - } - - #[test] - fn test_as_list(){ - let json_value = from_str("[1, 2, 3]").unwrap(); - let json_list = json_value.as_list(); - let expected_length = 3; - assert!(json_list.is_some() && json_list.unwrap().len() == expected_length); - } - - #[test] - fn test_is_string(){ - let json_value = from_str("\"dog\"").unwrap(); - assert!(json_value.is_string()); - } - - #[test] - fn test_as_string(){ - let json_value = from_str("\"dog\"").unwrap(); - let json_str = json_value.as_string(); - let expected_str = &"dog"; - assert_eq!(json_str, Some(expected_str)); - } - - #[test] - fn test_is_number(){ - let json_value = from_str("12").unwrap(); - assert!(json_value.is_number()); - } - - #[test] - fn test_as_number(){ - let json_value = from_str("12").unwrap(); - let json_num = json_value.as_number(); - let expected_num = 12f64; - assert!(json_num.is_some() && json_num.unwrap() == expected_num); - } - - #[test] - fn test_is_boolean(){ - let json_value = from_str("false").unwrap(); - assert!(json_value.is_boolean()); - } - - #[test] - fn test_as_boolean(){ - let json_value = from_str("false").unwrap(); - let json_bool = json_value.as_boolean(); - let expected_bool = false; - assert!(json_bool.is_some() && json_bool.unwrap() == expected_bool); - } - - #[test] - fn test_is_null(){ - let json_value = from_str("null").unwrap(); - assert!(json_value.is_null()); - } - - #[test] - fn test_as_null(){ - let json_value = from_str("null").unwrap(); - let json_null = json_value.as_null(); - let expected_null = (); - assert!(json_null.is_some() && json_null.unwrap() == expected_null); - } - - #[test] - fn test_encode_hashmap_with_numeric_key() { - use std::str::from_utf8; - use std::io::Writer; - use std::io::MemWriter; - use collections::HashMap; - let mut hm: HashMap = HashMap::new(); - hm.insert(1, true); - let mut mem_buf = MemWriter::new(); - { - let mut encoder = Encoder::new(&mut mem_buf as &mut io::Writer); - hm.encode(&mut encoder) - } - let bytes = mem_buf.unwrap(); - let json_str = from_utf8(bytes).unwrap(); - match from_str(json_str) { - Err(_) => fail!("Unable to parse json_str: {:?}", json_str), - _ => {} // it parsed and we are good to go - } - } - #[test] - fn test_prettyencode_hashmap_with_numeric_key() { - use std::str::from_utf8; - use std::io::Writer; - use std::io::MemWriter; - use collections::HashMap; - let mut hm: HashMap = HashMap::new(); - hm.insert(1, true); - let mut mem_buf = MemWriter::new(); - { - let mut encoder = PrettyEncoder::new(&mut mem_buf as &mut io::Writer); - hm.encode(&mut encoder) - } - let bytes = mem_buf.unwrap(); - let json_str = from_utf8(bytes).unwrap(); - match from_str(json_str) { - Err(_) => fail!("Unable to parse json_str: {:?}", json_str), - _ => {} // it parsed and we are good to go - } - } - #[test] - fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() { - use collections::HashMap; - use Decodable; - let json_str = "{\"1\":true}"; - let json_obj = match from_str(json_str) { - Err(_) => fail!("Unable to parse json_str: {:?}", json_str), - Ok(o) => o - }; - let mut decoder = Decoder::new(json_obj); - let _hm: HashMap = Decodable::decode(&mut decoder); - } -} - diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 86e03aae673..8a5829da9d6 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -34,31 +34,10 @@ pub use self::serialize::{Decoder, Encoder, Decodable, Encodable, DecoderHelpers, EncoderHelpers}; -// FIXME: remove _old.rs files after snapshot -#[cfg(not(stage0))] mod serialize; -#[cfg(not(stage0))] mod collection_impls; pub mod base64; -#[cfg(not(stage0))] pub mod ebml; pub mod hex; -#[cfg(not(stage0))] -pub mod json; - -#[cfg(stage0)] -#[path="./serialize_old.rs"] -pub mod serialize; - -#[cfg(stage0)] -#[path="./collection_impls_old.rs"] -mod collection_impls; - -#[cfg(stage0)] -#[path="./ebml_old.rs"] -pub mod ebml; - -#[cfg(stage0)] -#[path="./json_old.rs"] pub mod json; diff --git a/src/libserialize/serialize_old.rs b/src/libserialize/serialize_old.rs deleted file mode 100644 index 4043cbe65fe..00000000000 --- a/src/libserialize/serialize_old.rs +++ /dev/null @@ -1,688 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Support code for encoding and decoding types. - -/* -Core encoding and decoding interfaces. -*/ - -use std::path; -use std::rc::Rc; -use std::slice; - -pub trait Encoder { - // Primitive types: - fn emit_nil(&mut self); - fn emit_uint(&mut self, v: uint); - fn emit_u64(&mut self, v: u64); - fn emit_u32(&mut self, v: u32); - fn emit_u16(&mut self, v: u16); - fn emit_u8(&mut self, v: u8); - fn emit_int(&mut self, v: int); - fn emit_i64(&mut self, v: i64); - fn emit_i32(&mut self, v: i32); - fn emit_i16(&mut self, v: i16); - fn emit_i8(&mut self, v: i8); - fn emit_bool(&mut self, v: bool); - fn emit_f64(&mut self, v: f64); - fn emit_f32(&mut self, v: f32); - fn emit_char(&mut self, v: char); - fn emit_str(&mut self, v: &str); - - // Compound types: - fn emit_enum(&mut self, name: &str, f: |&mut Self|); - - fn emit_enum_variant(&mut self, - v_name: &str, - v_id: uint, - len: uint, - f: |&mut Self|); - fn emit_enum_variant_arg(&mut self, a_idx: uint, f: |&mut Self|); - - fn emit_enum_struct_variant(&mut self, - v_name: &str, - v_id: uint, - len: uint, - f: |&mut Self|); - fn emit_enum_struct_variant_field(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self|); - - fn emit_struct(&mut self, name: &str, len: uint, f: |&mut Self|); - fn emit_struct_field(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self|); - - fn emit_tuple(&mut self, len: uint, f: |&mut Self|); - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Self|); - - fn emit_tuple_struct(&mut self, name: &str, len: uint, f: |&mut Self|); - fn emit_tuple_struct_arg(&mut self, f_idx: uint, f: |&mut Self|); - - // Specialized types: - fn emit_option(&mut self, f: |&mut Self|); - fn emit_option_none(&mut self); - fn emit_option_some(&mut self, f: |&mut Self|); - - fn emit_seq(&mut self, len: uint, f: |this: &mut Self|); - fn emit_seq_elt(&mut self, idx: uint, f: |this: &mut Self|); - - fn emit_map(&mut self, len: uint, f: |&mut Self|); - fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Self|); - fn emit_map_elt_val(&mut self, idx: uint, f: |&mut Self|); -} - -pub trait Decoder { - // Primitive types: - fn read_nil(&mut self) -> (); - fn read_uint(&mut self) -> uint; - fn read_u64(&mut self) -> u64; - fn read_u32(&mut self) -> u32; - fn read_u16(&mut self) -> u16; - fn read_u8(&mut self) -> u8; - fn read_int(&mut self) -> int; - fn read_i64(&mut self) -> i64; - fn read_i32(&mut self) -> i32; - fn read_i16(&mut self) -> i16; - fn read_i8(&mut self) -> i8; - fn read_bool(&mut self) -> bool; - fn read_f64(&mut self) -> f64; - fn read_f32(&mut self) -> f32; - fn read_char(&mut self) -> char; - fn read_str(&mut self) -> ~str; - - // Compound types: - fn read_enum(&mut self, name: &str, f: |&mut Self| -> T) -> T; - - fn read_enum_variant(&mut self, - names: &[&str], - f: |&mut Self, uint| -> T) - -> T; - fn read_enum_variant_arg(&mut self, - a_idx: uint, - f: |&mut Self| -> T) - -> T; - - fn read_enum_struct_variant(&mut self, - names: &[&str], - f: |&mut Self, uint| -> T) - -> T; - fn read_enum_struct_variant_field(&mut self, - &f_name: &str, - f_idx: uint, - f: |&mut Self| -> T) - -> T; - - fn read_struct(&mut self, s_name: &str, len: uint, f: |&mut Self| -> T) - -> T; - fn read_struct_field(&mut self, - f_name: &str, - f_idx: uint, - f: |&mut Self| -> T) - -> T; - - fn read_tuple(&mut self, f: |&mut Self, uint| -> T) -> T; - fn read_tuple_arg(&mut self, a_idx: uint, f: |&mut Self| -> T) -> T; - - fn read_tuple_struct(&mut self, - s_name: &str, - f: |&mut Self, uint| -> T) - -> T; - fn read_tuple_struct_arg(&mut self, - a_idx: uint, - f: |&mut Self| -> T) - -> T; - - // Specialized types: - fn read_option(&mut self, f: |&mut Self, bool| -> T) -> T; - - fn read_seq(&mut self, f: |&mut Self, uint| -> T) -> T; - fn read_seq_elt(&mut self, idx: uint, f: |&mut Self| -> T) -> T; - - fn read_map(&mut self, f: |&mut Self, uint| -> T) -> T; - fn read_map_elt_key(&mut self, idx: uint, f: |&mut Self| -> T) -> T; - fn read_map_elt_val(&mut self, idx: uint, f: |&mut Self| -> T) -> T; -} - -pub trait Encodable { - fn encode(&self, s: &mut S); -} - -pub trait Decodable { - fn decode(d: &mut D) -> Self; -} - -impl Encodable for uint { - fn encode(&self, s: &mut S) { - s.emit_uint(*self) - } -} - -impl Decodable for uint { - fn decode(d: &mut D) -> uint { - d.read_uint() - } -} - -impl Encodable for u8 { - fn encode(&self, s: &mut S) { - s.emit_u8(*self) - } -} - -impl Decodable for u8 { - fn decode(d: &mut D) -> u8 { - d.read_u8() - } -} - -impl Encodable for u16 { - fn encode(&self, s: &mut S) { - s.emit_u16(*self) - } -} - -impl Decodable for u16 { - fn decode(d: &mut D) -> u16 { - d.read_u16() - } -} - -impl Encodable for u32 { - fn encode(&self, s: &mut S) { - s.emit_u32(*self) - } -} - -impl Decodable for u32 { - fn decode(d: &mut D) -> u32 { - d.read_u32() - } -} - -impl Encodable for u64 { - fn encode(&self, s: &mut S) { - s.emit_u64(*self) - } -} - -impl Decodable for u64 { - fn decode(d: &mut D) -> u64 { - d.read_u64() - } -} - -impl Encodable for int { - fn encode(&self, s: &mut S) { - s.emit_int(*self) - } -} - -impl Decodable for int { - fn decode(d: &mut D) -> int { - d.read_int() - } -} - -impl Encodable for i8 { - fn encode(&self, s: &mut S) { - s.emit_i8(*self) - } -} - -impl Decodable for i8 { - fn decode(d: &mut D) -> i8 { - d.read_i8() - } -} - -impl Encodable for i16 { - fn encode(&self, s: &mut S) { - s.emit_i16(*self) - } -} - -impl Decodable for i16 { - fn decode(d: &mut D) -> i16 { - d.read_i16() - } -} - -impl Encodable for i32 { - fn encode(&self, s: &mut S) { - s.emit_i32(*self) - } -} - -impl Decodable for i32 { - fn decode(d: &mut D) -> i32 { - d.read_i32() - } -} - -impl Encodable for i64 { - fn encode(&self, s: &mut S) { - s.emit_i64(*self) - } -} - -impl Decodable for i64 { - fn decode(d: &mut D) -> i64 { - d.read_i64() - } -} - -impl<'a, S:Encoder> Encodable for &'a str { - fn encode(&self, s: &mut S) { - s.emit_str(*self) - } -} - -impl Encodable for ~str { - fn encode(&self, s: &mut S) { - s.emit_str(*self) - } -} - -impl Decodable for ~str { - fn decode(d: &mut D) -> ~str { - d.read_str() - } -} - -impl Encodable for f32 { - fn encode(&self, s: &mut S) { - s.emit_f32(*self) - } -} - -impl Decodable for f32 { - fn decode(d: &mut D) -> f32 { - d.read_f32() - } -} - -impl Encodable for f64 { - fn encode(&self, s: &mut S) { - s.emit_f64(*self) - } -} - -impl Decodable for f64 { - fn decode(d: &mut D) -> f64 { - d.read_f64() - } -} - -impl Encodable for bool { - fn encode(&self, s: &mut S) { - s.emit_bool(*self) - } -} - -impl Decodable for bool { - fn decode(d: &mut D) -> bool { - d.read_bool() - } -} - -impl Encodable for char { - fn encode(&self, s: &mut S) { - s.emit_char(*self) - } -} - -impl Decodable for char { - fn decode(d: &mut D) -> char { - d.read_char() - } -} - -impl Encodable for () { - fn encode(&self, s: &mut S) { - s.emit_nil() - } -} - -impl Decodable for () { - fn decode(d: &mut D) -> () { - d.read_nil() - } -} - -impl<'a, S:Encoder,T:Encodable> Encodable for &'a T { - fn encode(&self, s: &mut S) { - (**self).encode(s) - } -} - -impl> Encodable for ~T { - fn encode(&self, s: &mut S) { - (**self).encode(s) - } -} - -impl> Decodable for ~T { - fn decode(d: &mut D) -> ~T { - ~Decodable::decode(d) - } -} - -impl> Encodable for @T { - fn encode(&self, s: &mut S) { - (**self).encode(s) - } -} - -impl> Encodable for Rc { - #[inline] - fn encode(&self, s: &mut S) { - (**self).encode(s) - } -} - -impl> Decodable for Rc { - #[inline] - fn decode(d: &mut D) -> Rc { - Rc::new(Decodable::decode(d)) - } -} - -impl + 'static> Decodable for @T { - fn decode(d: &mut D) -> @T { - @Decodable::decode(d) - } -} - -impl<'a, S:Encoder,T:Encodable> Encodable for &'a [T] { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)) - } - }) - } -} - -impl> Encodable for ~[T] { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)) - } - }) - } -} - -impl> Decodable for ~[T] { - fn decode(d: &mut D) -> ~[T] { - d.read_seq(|d, len| { - slice::from_fn(len, |i| { - d.read_seq_elt(i, |d| Decodable::decode(d)) - }) - }) - } -} - -impl> Encodable for Vec { - fn encode(&self, s: &mut S) { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - s.emit_seq_elt(i, |s| e.encode(s)) - } - }) - } -} - -impl> Decodable for Vec { - fn decode(d: &mut D) -> Vec { - d.read_seq(|d, len| { - Vec::from_fn(len, |i| { - d.read_seq_elt(i, |d| Decodable::decode(d)) - }) - }) - } -} - -impl> Encodable for Option { - fn encode(&self, s: &mut S) { - s.emit_option(|s| { - match *self { - None => s.emit_option_none(), - Some(ref v) => s.emit_option_some(|s| v.encode(s)), - } - }) - } -} - -impl> Decodable for Option { - fn decode(d: &mut D) -> Option { - d.read_option(|d, b| { - if b { - Some(Decodable::decode(d)) - } else { - None - } - }) - } -} - -impl,T1:Encodable> Encodable for (T0, T1) { - fn encode(&self, s: &mut S) { - match *self { - (ref t0, ref t1) => { - s.emit_seq(2, |s| { - s.emit_seq_elt(0, |s| t0.encode(s)); - s.emit_seq_elt(1, |s| t1.encode(s)); - }) - } - } - } -} - -impl,T1:Decodable> Decodable for (T0, T1) { - fn decode(d: &mut D) -> (T0, T1) { - d.read_seq(|d, len| { - assert_eq!(len, 2); - ( - d.read_seq_elt(0, |d| Decodable::decode(d)), - d.read_seq_elt(1, |d| Decodable::decode(d)) - ) - }) - } -} - -impl< - S: Encoder, - T0: Encodable, - T1: Encodable, - T2: Encodable -> Encodable for (T0, T1, T2) { - fn encode(&self, s: &mut S) { - match *self { - (ref t0, ref t1, ref t2) => { - s.emit_seq(3, |s| { - s.emit_seq_elt(0, |s| t0.encode(s)); - s.emit_seq_elt(1, |s| t1.encode(s)); - s.emit_seq_elt(2, |s| t2.encode(s)); - }) - } - } - } -} - -impl< - D: Decoder, - T0: Decodable, - T1: Decodable, - T2: Decodable -> Decodable for (T0, T1, T2) { - fn decode(d: &mut D) -> (T0, T1, T2) { - d.read_seq(|d, len| { - assert_eq!(len, 3); - ( - d.read_seq_elt(0, |d| Decodable::decode(d)), - d.read_seq_elt(1, |d| Decodable::decode(d)), - d.read_seq_elt(2, |d| Decodable::decode(d)) - ) - }) - } -} - -impl< - S: Encoder, - T0: Encodable, - T1: Encodable, - T2: Encodable, - T3: Encodable -> Encodable for (T0, T1, T2, T3) { - fn encode(&self, s: &mut S) { - match *self { - (ref t0, ref t1, ref t2, ref t3) => { - s.emit_seq(4, |s| { - s.emit_seq_elt(0, |s| t0.encode(s)); - s.emit_seq_elt(1, |s| t1.encode(s)); - s.emit_seq_elt(2, |s| t2.encode(s)); - s.emit_seq_elt(3, |s| t3.encode(s)); - }) - } - } - } -} - -impl< - D: Decoder, - T0: Decodable, - T1: Decodable, - T2: Decodable, - T3: Decodable -> Decodable for (T0, T1, T2, T3) { - fn decode(d: &mut D) -> (T0, T1, T2, T3) { - d.read_seq(|d, len| { - assert_eq!(len, 4); - ( - d.read_seq_elt(0, |d| Decodable::decode(d)), - d.read_seq_elt(1, |d| Decodable::decode(d)), - d.read_seq_elt(2, |d| Decodable::decode(d)), - d.read_seq_elt(3, |d| Decodable::decode(d)) - ) - }) - } -} - -impl< - S: Encoder, - T0: Encodable, - T1: Encodable, - T2: Encodable, - T3: Encodable, - T4: Encodable -> Encodable for (T0, T1, T2, T3, T4) { - fn encode(&self, s: &mut S) { - match *self { - (ref t0, ref t1, ref t2, ref t3, ref t4) => { - s.emit_seq(5, |s| { - s.emit_seq_elt(0, |s| t0.encode(s)); - s.emit_seq_elt(1, |s| t1.encode(s)); - s.emit_seq_elt(2, |s| t2.encode(s)); - s.emit_seq_elt(3, |s| t3.encode(s)); - s.emit_seq_elt(4, |s| t4.encode(s)); - }) - } - } - } -} - -impl< - D: Decoder, - T0: Decodable, - T1: Decodable, - T2: Decodable, - T3: Decodable, - T4: Decodable -> Decodable for (T0, T1, T2, T3, T4) { - fn decode(d: &mut D) -> (T0, T1, T2, T3, T4) { - d.read_seq(|d, len| { - assert_eq!(len, 5); - ( - d.read_seq_elt(0, |d| Decodable::decode(d)), - d.read_seq_elt(1, |d| Decodable::decode(d)), - d.read_seq_elt(2, |d| Decodable::decode(d)), - d.read_seq_elt(3, |d| Decodable::decode(d)), - d.read_seq_elt(4, |d| Decodable::decode(d)) - ) - }) - } -} - -impl Encodable for path::posix::Path { - fn encode(&self, e: &mut E) { - self.as_vec().encode(e) - } -} - -impl Decodable for path::posix::Path { - fn decode(d: &mut D) -> path::posix::Path { - let bytes: ~[u8] = Decodable::decode(d); - path::posix::Path::new(bytes) - } -} - -impl Encodable for path::windows::Path { - fn encode(&self, e: &mut E) { - self.as_vec().encode(e) - } -} - -impl Decodable for path::windows::Path { - fn decode(d: &mut D) -> path::windows::Path { - let bytes: ~[u8] = Decodable::decode(d); - path::windows::Path::new(bytes) - } -} - -// ___________________________________________________________________________ -// Helper routines -// -// In some cases, these should eventually be coded as traits. - -pub trait EncoderHelpers { - fn emit_from_vec(&mut self, v: &[T], f: |&mut Self, v: &T|); -} - -impl EncoderHelpers for S { - fn emit_from_vec(&mut self, v: &[T], f: |&mut S, &T|) { - self.emit_seq(v.len(), |this| { - for (i, e) in v.iter().enumerate() { - this.emit_seq_elt(i, |this| { - f(this, e) - }) - } - }) - } -} - -pub trait DecoderHelpers { - fn read_to_vec(&mut self, f: |&mut Self| -> T) -> ~[T]; -} - -impl DecoderHelpers for D { - fn read_to_vec(&mut self, f: |&mut D| -> T) -> ~[T] { - self.read_seq(|this, len| { - slice::from_fn(len, |i| { - this.read_seq_elt(i, |this| f(this)) - }) - }) - } -} - diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs index e956a1cdf1d..f18bd27e18f 100644 --- a/src/libstd/cmp.rs +++ b/src/libstd/cmp.rs @@ -42,7 +42,6 @@ fn ne(&self, other: &Self) -> bool { !self.eq(other) } } /// Trait for equality comparisons where `a == b` and `a != b` are strict inverses. -#[cfg(not(stage0))] pub trait TotalEq: Eq { // FIXME #13101: this method is used solely by #[deriving] to // assert that every component of a type implements #[deriving] @@ -56,15 +55,6 @@ pub trait TotalEq: Eq { fn assert_receiver_is_total_eq(&self) {} } -#[cfg(stage0)] -pub trait TotalEq: Eq { - /// This method must return the same value as `eq`. It exists to prevent - /// deriving `TotalEq` from fields not implementing the `TotalEq` trait. - fn equals(&self, other: &Self) -> bool { - self.eq(other) - } -} - macro_rules! totaleq_impl( ($t:ty) => { impl TotalEq for $t {} diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs index c01b09dd5ac..76aa0d42548 100644 --- a/src/libstd/kinds.rs +++ b/src/libstd/kinds.rs @@ -33,14 +33,6 @@ pub trait Sized { } /// Types that can be copied by simply copying bits (i.e. `memcpy`). -#[cfg(stage0)] -#[lang="pod"] -pub trait Copy { - // Empty. -} - -/// Types that can be copied by simply copying bits (i.e. `memcpy`). -#[cfg(not(stage0))] #[lang="copy"] pub trait Copy { // Empty. @@ -270,19 +262,10 @@ pub mod marker { /// A type which is considered "not POD", meaning that it is not /// implicitly copyable. This is typically embedded in other types to /// ensure that they are never copied, even if they lack a destructor. - #[cfg(not(stage0))] #[lang="no_copy_bound"] #[deriving(Eq,Clone)] pub struct NoCopy; - /// A type which is considered "not POD", meaning that it is not - /// implicitly copyable. This is typically embedded in other types to - /// ensure that they are never copied, even if they lack a destructor. - #[cfg(stage0)] - #[lang="no_pod_bound"] - #[deriving(Eq,Clone)] - pub struct NoCopy; - /// A type which is considered "not sharable", meaning that /// its contents are not threadsafe, hence they cannot be /// shared between tasks. diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a44fbce421b..a6b34508113 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -98,29 +98,12 @@ fn ne(&self, other: &Ident) -> bool { /// A mark represents a unique id associated with a macro expansion pub type Mrk = u32; -// FIXME: remove stage0 Encodables after snapshot -#[cfg(stage0)] -impl Encodable for Ident { - fn encode(&self, s: &mut S) { - s.emit_str(token::get_ident(*self).get()); - } -} - -#[cfg(stage0)] -impl Decodable for Ident { - fn decode(d: &mut D) -> Ident { - str_to_ident(d.read_str()) - } -} - -#[cfg(not(stage0))] impl, E> Encodable for Ident { fn encode(&self, s: &mut S) -> Result<(), E> { s.emit_str(token::get_ident(*self).get()) } } -#[cfg(not(stage0))] impl, E> Decodable for Ident { fn decode(d: &mut D) -> Result { Ok(str_to_ident(try!(d.read_str()))) @@ -1183,26 +1166,7 @@ mod test { use super::*; // are ASTs encodable? - // FIXME: remove stage0 test after snapshot #[test] - #[cfg(stage0)] - fn check_asts_encodable() { - let e = Crate { - module: Mod {view_items: Vec::new(), items: Vec::new()}, - attrs: Vec::new(), - config: Vec::new(), - span: Span { - lo: BytePos(10), - hi: BytePos(20), - expn_info: None, - }, - }; - // doesn't matter which encoder we use.... - let _f = &e as &serialize::Encodable; - } - - #[test] - #[cfg(not(stage0))] fn check_asts_encodable() { use std::io; let e = Crate { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index f3ff7f97ee2..974868c1610 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -110,23 +110,6 @@ fn ne(&self, other: &Span) -> bool { !(*self).eq(other) } impl TotalEq for Span {} -// FIXME: remove stage0 Encodables/Decodables after snapshot -#[cfg(stage0)] -impl Encodable for Span { - /* Note #1972 -- spans are encoded but not decoded */ - fn encode(&self, s: &mut S) { - s.emit_nil() - } -} - -#[cfg(stage0)] -impl Decodable for Span { - fn decode(_d: &mut D) -> Span { - DUMMY_SP - } -} - -#[cfg(not(stage0))] impl, E> Encodable for Span { /* Note #1972 -- spans are encoded but not decoded */ fn encode(&self, s: &mut S) -> Result<(), E> { @@ -134,7 +117,6 @@ fn encode(&self, s: &mut S) -> Result<(), E> { } } -#[cfg(not(stage0))] impl, E> Decodable for Span { fn decode(_d: &mut D) -> Result { Ok(DUMMY_SP) diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index c4ce3c5cb55..33829212686 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -131,29 +131,12 @@ fn from_iterator>(mut iter: I) -> OwnedSlice { } } -// FIXME: remove stage0 Encodables/Decodables after snapshot -#[cfg(stage0)] -impl> Encodable for OwnedSlice { - fn encode(&self, s: &mut S) { - self.as_slice().encode(s) - } -} - -#[cfg(stage0)] -impl> Decodable for OwnedSlice { - fn decode(d: &mut D) -> OwnedSlice { - OwnedSlice::from_vec(Decodable::decode(d)) - } -} - -#[cfg(not(stage0))] impl, T: Encodable, E> Encodable for OwnedSlice { fn encode(&self, s: &mut S) -> Result<(), E> { self.as_slice().encode(s) } } -#[cfg(not(stage0))] impl, T: Decodable, E> Decodable for OwnedSlice { fn decode(d: &mut D) -> Result, E> { Ok(OwnedSlice::from_vec(match Decodable::decode(d) { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 2df93deea14..38be76e7e71 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -288,16 +288,6 @@ mod test { use util::parser_testing::{string_to_expr, string_to_item}; use util::parser_testing::string_to_stmt; - // FIXME: remove stage0 to_json_str after snapshot - #[cfg(stage0)] - fn to_json_str<'a, E: Encodable>>(val: &E) -> ~str { - let mut writer = MemWriter::new(); - let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer); - val.encode(&mut encoder); - str::from_utf8_owned(writer.unwrap()).unwrap() - } - - #[cfg(not(stage0))] fn to_json_str<'a, E: Encodable, io::IoError>>(val: &E) -> ~str { let mut writer = MemWriter::new(); let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 7bb920bdf56..e9cc5e10b38 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -602,29 +602,12 @@ fn equiv(&self, other: & &'a str) -> bool { } } -// FIXME: remove stage0 Encodables/Decodables after snapshot -#[cfg(stage0)] -impl Decodable for InternedString { - fn decode(d: &mut D) -> InternedString { - get_name(get_ident_interner().intern(d.read_str())) - } -} - -#[cfg(stage0)] -impl Encodable for InternedString { - fn encode(&self, e: &mut E) { - e.emit_str(self.string.as_slice()) - } -} - -#[cfg(not(stage0))] impl, E> Decodable for InternedString { fn decode(d: &mut D) -> Result { Ok(get_name(get_ident_interner().intern(try!(d.read_str())))) } } -#[cfg(not(stage0))] impl, E> Encodable for InternedString { fn encode(&self, s: &mut S) -> Result<(), E> { s.emit_str(self.string.as_slice()) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 751dc58450f..bcfd9ae758b 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1018,22 +1018,6 @@ fn to_json(&self) -> json::Json { } } -// FIXME: remove decode_ after snapshot -#[cfg(stage0)] -fn decode_(json: Json) -> MetricMap { - let mut decoder = json::Decoder::new(json); - MetricMap(Decodable::decode(&mut decoder)) -} - -#[cfg(not(stage0))] -fn decode_(json: Json) -> MetricMap { - let mut decoder = json::Decoder::new(json); - MetricMap(match Decodable::decode(&mut decoder) { - Ok(t) => t, - Err(e) => fail!("failure decoding JSON: {}", e) - }) -} - impl MetricMap { @@ -1051,7 +1035,11 @@ pub fn load(p: &Path) -> MetricMap { assert!(p.exists()); let mut f = File::open(p).unwrap(); let value = json::from_reader(&mut f as &mut io::Reader).unwrap(); - decode_(value) + let mut decoder = json::Decoder::new(value); + MetricMap(match Decodable::decode(&mut decoder) { + Ok(t) => t, + Err(e) => fail!("failure decoding JSON: {}", e) + }) } /// Write MetricDiff to a file. diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs index 0065c90c91a..19bd197f0e8 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -490,24 +490,6 @@ fn eq(&self, other: &Uuid) -> bool { impl TotalEq for Uuid {} // FIXME #9845: Test these more thoroughly -// FIXME: remove stage0 Encodable/Decodable after snapshot -#[cfg(stage0)] -impl Encodable for Uuid { - /// Encode a UUID as a hypenated string - fn encode(&self, e: &mut T) { - e.emit_str(self.to_hyphenated_str()) - } -} - -#[cfg(stage0)] -impl Decodable for Uuid { - /// Decode a UUID from a string - fn decode(d: &mut T) -> Uuid { - from_str(d.read_str()).unwrap() - } -} - -#[cfg(not(stage0))] impl, E> Encodable for Uuid { /// Encode a UUID as a hypenated string fn encode(&self, e: &mut T) -> Result<(), E> { @@ -515,7 +497,6 @@ fn encode(&self, e: &mut T) -> Result<(), E> { } } -#[cfg(not(stage0))] impl, E> Decodable for Uuid { /// Decode a UUID from a string fn decode(d: &mut T) -> Result { @@ -547,17 +528,6 @@ mod test { use std::str; use std::io::MemWriter; - // FIXME: remove unwrap_ after snapshot - #[cfg(stage0)] - fn unwrap_(t: T) -> T { - t - } - - #[cfg(not(stage0))] - fn unwrap_(t: Result) -> T { - t.unwrap() - } - #[test] fn test_nil() { let nil = Uuid::nil(); @@ -829,7 +799,7 @@ fn test_serialize_round_trip() { let mut wr = MemWriter::new(); let _ = u.encode(&mut ebml::writer::Encoder(&mut wr)); let doc = ebml::reader::Doc(wr.get_ref()); - let u2 = unwrap_(Decodable::decode(&mut ebml::reader::Decoder(doc))); + let u2 = Decodable::decode(&mut ebml::reader::Decoder(doc)).unwrap(); assert_eq!(u, u2); } diff --git a/src/snapshots.txt b/src/snapshots.txt index f7f1c2d6aa3..59ea9834ed7 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,11 @@ +S 2014-03-28 b8601a3 + freebsd-x86_64 c6b0651b2a90697754920ad381c13f9b7942ab47 + linux-i386 3bef5684fd0582fbd4ddebd4514182d4f72924f7 + linux-x86_64 a7b2af1076d48e4a687a71a21478293e834349bd + macos-i386 41fb091c3bf5f0ebe9341f26129be82782266ddd + macos-x86_64 22b884a3876cb3e40ad942ad68a496b5f239fca5 + winnt-i386 65174e80fbf69f92e41110b0bcc7e15704ca359b + S 2014-03-22 94e4e91 freebsd-x86_64 7793127e1b9ad22cb2e020f9bb01f34526cc4656 linux-i386 aa53699d32d7acb86a6447f988c4ac73ac310bab