}
}
-// FIXME: remove unwrap_ after snapshot
-#[cfg(stage0)]
-fn unwrap_<T>(t: T) -> T {
- t
-}
-
-#[cfg(not(stage0))]
-fn unwrap_<T, E>(r: Result<T, E>) -> T {
- r.unwrap()
-}
-
pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
-> ast::Crate {
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() {
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)
pub type Cmd = @crate_metadata;
-// FIXME: remove unwrap_ after a snapshot
-#[cfg(stage0)]
-fn unwrap_<T>(t: T) -> T {
- t
-}
-
-#[cfg(not(stage0))]
-fn unwrap_<T, E>(r: Result<T, E>) -> 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
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;
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
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,
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,
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;
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 {
- t
-}
-
-#[cfg(not(stage0))]
-fn unwrap_<T, E>(r: Result<T, E>) -> T {
- r.unwrap()
-}
-
-#[cfg(stage0)]
-fn wrap_<T>(t: T) -> T {
- t
-}
-
-#[cfg(not(stage0))]
-fn wrap_<T, E>(t: T) -> Result<T, E> {
- Ok(t)
-}
-
-
-
// ______________________________________________________________________
// Top-level methods.
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,
fn emit_def_id(&mut self, did: ast::DefId);
}
-#[cfg(stage0)]
-impl<S:serialize::Encoder> def_id_encoder_helpers for S {
- fn emit_def_id(&mut self, did: ast::DefId) {
- did.encode(self)
- }
-}
-
-#[cfg(not(stage0))]
impl<S:serialize::Encoder<E>, E> def_id_encoder_helpers for S {
fn emit_def_id(&mut self, did: ast::DefId) {
- unwrap_(did.encode(self))
+ did.encode(self).unwrap()
}
}
cdata: @cstore::crate_metadata) -> ast::DefId;
}
-#[cfg(stage0)]
-impl<D:serialize::Decoder> 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<D:serialize::Decoder<E>, 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)
}
}
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> {
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)
}
// 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 {
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)
}
}
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)
}
}
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)
});
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()
}
}
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,
// 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))
})
})
}
})
}
}
- }))
+ }).unwrap()
}
pub trait vtable_decoder_helpers {
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()
}
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()
}
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()
}
}
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))
});
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| {
})
});
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)));
}
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)))
})
}
}
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());
})
}
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))
});
})
})
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<ty::t> {
- 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()
}
// 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(
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 = ~"";
}
fn read_tys(&mut self, xcx: &ExtendedDecodeContext) -> Vec<ty::t> {
- 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<ty::Region> =
- 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)),
_ => fail!("bad enum variant for ty::AutoAdjustment")
})
})
- }))
+ }).unwrap()
}
fn convert_def_id(&mut self,
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 => {
}
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));
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)]
return pm.run_plugins(krate);
}
-// FIXME: remove unwrap_ after snapshot
-#[cfg(stage0)]
-fn unwrap_<T>(t: T) -> T {
- t
-}
-
-#[cfg(not(stage0))]
-fn unwrap_<T, E>(r: Result<T, E>) -> 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<Output, ~str> {
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"),
};
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()
};
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<S>
-> Encodable<S> for DList<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<D:Decoder,T:Decodable<D>> Decodable<D> for DList<T> {
- fn decode(d: &mut D) -> DList<T> {
- 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<S>
-> Encodable<S> for RingBuf<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<D:Decoder,T:Decodable<D>> Decodable<D> for RingBuf<T> {
- fn decode(d: &mut D) -> RingBuf<T> {
- 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<E> + Eq + TotalOrd,
- V: Encodable<E> + Eq
-> Encodable<E> for TreeMap<K, V> {
- 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<D> + Eq + TotalOrd,
- V: Decodable<D> + Eq
-> Decodable<D> for TreeMap<K, V> {
- fn decode(d: &mut D) -> TreeMap<K, V> {
- 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<S> + Eq + TotalOrd
-> Encodable<S> for TreeSet<T> {
- 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<D> + Eq + TotalOrd
-> Decodable<D> for TreeSet<T> {
- fn decode(d: &mut D) -> TreeSet<T> {
- 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<S> + CLike
-> Encodable<S> for EnumSet<T> {
- 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<D> + CLike
-> Decodable<D> for EnumSet<T> {
- fn decode(d: &mut D) -> EnumSet<T> {
- 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<E> + Hash<S> + TotalEq,
- V: Encodable<E>,
- S,
- H: Hasher<S>
-> Encodable<E> for HashMap<K, V, H> {
- 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<D> + Hash<S> + TotalEq,
- V: Decodable<D>,
- S,
- H: Hasher<S> + Default
-> Decodable<D> for HashMap<K, V, H> {
- fn decode(d: &mut D) -> HashMap<K, V, H> {
- 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<E> + Hash<S> + TotalEq,
- S,
- H: Hasher<S>
-> Encodable<E> for HashSet<T, H> {
- 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<D> + Hash<S> + TotalEq,
- S,
- H: Hasher<S> + Default
-> Decodable<D> for HashSet<T, H> {
- fn decode(d: &mut D) -> HashSet<T, H> {
- 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<E>
-> Encodable<E> for TrieMap<V> {
- 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<D>
-> Decodable<D> for TrieMap<V> {
- fn decode(d: &mut D) -> TrieMap<V> {
- 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<S: Encoder> Encodable<S> 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<D: Decoder> Decodable<D> 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
- })
- }
-}
-
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Doc<'a>> {
- 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<T>(&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<R>(&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<T>(&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<T>(&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<T>(&mut self,
- idx: uint,
- f: |&mut Decoder<'doc>| -> T) -> T {
- debug!("read_enum_variant_arg(idx={})", idx);
- f(self)
- }
-
- fn read_enum_struct_variant<T>(&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<T>(&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<T>(&mut self,
- name: &str,
- _: uint,
- f: |&mut Decoder<'doc>| -> T)
- -> T {
- debug!("read_struct(name={})", name);
- f(self)
- }
-
- fn read_struct_field<T>(&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<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
- debug!("read_tuple()");
- self.read_seq(f)
- }
-
- fn read_tuple_arg<T>(&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<T>(&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<T>(&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<T>(&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<T>(&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<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
- -> T {
- debug!("read_seq_elt(idx={})", idx);
- self.push_doc(EsVecElt, f)
- }
-
- fn read_map<T>(&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<T>(&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<T>(&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<int>) {
- 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;
- }
- });
- }
-}
-
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T:Encodable<Encoder<'a>>>(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<T:Encodable<Encoder<'a>>>(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<E: ::Encoder> Encodable<E> 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<f64> {
- 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<bool> {
- 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<T> {
- priv rdr: T,
- priv ch: Option<char>,
- priv line: uint,
- priv col: uint,
-}
-
-impl<T: Iterator<char>> Parser<T> {
- /// Decode a json value from an Iterator<char>
- pub fn new(rdr: T) -> Parser<T> {
- let mut p = Parser {
- rdr: rdr,
- ch: Some('\x00'),
- line: 1,
- col: 0,
- };
- p.bump();
- p
- }
-}
-
-impl<T: Iterator<char>> Parser<T> {
- pub fn parse(&mut self) -> Result<Json, Error> {
- 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<T : Iterator<char>> Parser<T> {
- 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<char> {
- self.bump();
- self.ch
- }
- fn ch_is(&self, c: char) -> bool {
- self.ch == Some(c)
- }
-
- fn error<T>(&self, msg: ~str) -> Result<T, Error> {
- Err(Error { line: self.line, col: self.col, msg: msg })
- }
-
- fn parse_value(&mut self) -> Result<Json, Error> {
- 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<Json, Error> {
- 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<Json, Error> {
- 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<f64, Error> {
- 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<f64, Error> {
- 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<f64, Error> {
- 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<Json, Error> {
- 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<Json, Error> {
- 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<Json, Error> {
- 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<Json, Error> {
- 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<uint, V> 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<T>(&mut self, name: &str, f: |&mut Decoder| -> T) -> T {
- debug!("read_enum({})", name);
- f(self)
- }
-
- fn read_enum_variant<T>(&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<T>(&mut self, idx: uint, f: |&mut Decoder| -> T)
- -> T {
- debug!("read_enum_variant_arg(idx={})", idx);
- f(self)
- }
-
- fn read_enum_struct_variant<T>(&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<T>(&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<T>(&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<T>(&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<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T {
- debug!("read_tuple()");
- self.read_seq(f)
- }
-
- fn read_tuple_arg<T>(&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<T>(&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<T>(&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<T>(&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<T>(&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<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T {
- debug!("read_seq_elt(idx={})", idx);
- f(self)
- }
-
- fn read_map<T>(&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<T>(&mut self, idx: uint, f: |&mut Decoder| -> T)
- -> T {
- debug!("read_map_elt_key(idx={})", idx);
- f(self)
- }
-
- fn read_map_elt_val<T>(&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<A:ToJson,B:ToJson> ToJson for (A, B) {
- fn to_json(&self) -> Json {
- match *self {
- (ref a, ref b) => {
- List(~[a.to_json(), b.to_json()])
- }
- }
- }
-}
-
-impl<A:ToJson,B:ToJson,C:ToJson> 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<A:ToJson> ToJson for ~[A] {
- fn to_json(&self) -> Json { List(self.map(|elt| elt.to_json())) }
-}
-
-impl<A:ToJson> 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<A:ToJson> 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<A:ToJson> ToJson for Option<A> {
- 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<T: Decodable<Decoder>>(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::<DecodeStruct>("[]", "object but found list");
- check_err::<DecodeStruct>("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}",
- "number but found boolean");
- check_err::<DecodeStruct>("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}",
- "boolean but found list");
- check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}",
- "string but found object");
- check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}",
- "list but found null");
- check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\"}",
- "'w' field in object");
- }
- #[test]
- fn test_decode_errors_enum() {
- check_err::<DecodeEnum>("{}",
- "'variant' field in object");
- check_err::<DecodeEnum>("{\"variant\": 1}",
- "string but found number");
- check_err::<DecodeEnum>("{\"variant\": \"A\"}",
- "'fields' field in object");
- check_err::<DecodeEnum>("{\"variant\": \"A\", \"fields\": null}",
- "list but found null");
- check_err::<DecodeEnum>("{\"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<uint, bool> = 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<uint, bool> = 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<uint, bool> = Decodable::decode(&mut decoder);
- }
-}
-
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;
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T>(&mut self, name: &str, f: |&mut Self| -> T) -> T;
-
- fn read_enum_variant<T>(&mut self,
- names: &[&str],
- f: |&mut Self, uint| -> T)
- -> T;
- fn read_enum_variant_arg<T>(&mut self,
- a_idx: uint,
- f: |&mut Self| -> T)
- -> T;
-
- fn read_enum_struct_variant<T>(&mut self,
- names: &[&str],
- f: |&mut Self, uint| -> T)
- -> T;
- fn read_enum_struct_variant_field<T>(&mut self,
- &f_name: &str,
- f_idx: uint,
- f: |&mut Self| -> T)
- -> T;
-
- fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Self| -> T)
- -> T;
- fn read_struct_field<T>(&mut self,
- f_name: &str,
- f_idx: uint,
- f: |&mut Self| -> T)
- -> T;
-
- fn read_tuple<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
- fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Self| -> T) -> T;
-
- fn read_tuple_struct<T>(&mut self,
- s_name: &str,
- f: |&mut Self, uint| -> T)
- -> T;
- fn read_tuple_struct_arg<T>(&mut self,
- a_idx: uint,
- f: |&mut Self| -> T)
- -> T;
-
- // Specialized types:
- fn read_option<T>(&mut self, f: |&mut Self, bool| -> T) -> T;
-
- fn read_seq<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
- fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
-
- fn read_map<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
- fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
- fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
-}
-
-pub trait Encodable<S:Encoder> {
- fn encode(&self, s: &mut S);
-}
-
-pub trait Decodable<D:Decoder> {
- fn decode(d: &mut D) -> Self;
-}
-
-impl<S:Encoder> Encodable<S> for uint {
- fn encode(&self, s: &mut S) {
- s.emit_uint(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for uint {
- fn decode(d: &mut D) -> uint {
- d.read_uint()
- }
-}
-
-impl<S:Encoder> Encodable<S> for u8 {
- fn encode(&self, s: &mut S) {
- s.emit_u8(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for u8 {
- fn decode(d: &mut D) -> u8 {
- d.read_u8()
- }
-}
-
-impl<S:Encoder> Encodable<S> for u16 {
- fn encode(&self, s: &mut S) {
- s.emit_u16(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for u16 {
- fn decode(d: &mut D) -> u16 {
- d.read_u16()
- }
-}
-
-impl<S:Encoder> Encodable<S> for u32 {
- fn encode(&self, s: &mut S) {
- s.emit_u32(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for u32 {
- fn decode(d: &mut D) -> u32 {
- d.read_u32()
- }
-}
-
-impl<S:Encoder> Encodable<S> for u64 {
- fn encode(&self, s: &mut S) {
- s.emit_u64(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for u64 {
- fn decode(d: &mut D) -> u64 {
- d.read_u64()
- }
-}
-
-impl<S:Encoder> Encodable<S> for int {
- fn encode(&self, s: &mut S) {
- s.emit_int(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for int {
- fn decode(d: &mut D) -> int {
- d.read_int()
- }
-}
-
-impl<S:Encoder> Encodable<S> for i8 {
- fn encode(&self, s: &mut S) {
- s.emit_i8(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for i8 {
- fn decode(d: &mut D) -> i8 {
- d.read_i8()
- }
-}
-
-impl<S:Encoder> Encodable<S> for i16 {
- fn encode(&self, s: &mut S) {
- s.emit_i16(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for i16 {
- fn decode(d: &mut D) -> i16 {
- d.read_i16()
- }
-}
-
-impl<S:Encoder> Encodable<S> for i32 {
- fn encode(&self, s: &mut S) {
- s.emit_i32(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for i32 {
- fn decode(d: &mut D) -> i32 {
- d.read_i32()
- }
-}
-
-impl<S:Encoder> Encodable<S> for i64 {
- fn encode(&self, s: &mut S) {
- s.emit_i64(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for i64 {
- fn decode(d: &mut D) -> i64 {
- d.read_i64()
- }
-}
-
-impl<'a, S:Encoder> Encodable<S> for &'a str {
- fn encode(&self, s: &mut S) {
- s.emit_str(*self)
- }
-}
-
-impl<S:Encoder> Encodable<S> for ~str {
- fn encode(&self, s: &mut S) {
- s.emit_str(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for ~str {
- fn decode(d: &mut D) -> ~str {
- d.read_str()
- }
-}
-
-impl<S:Encoder> Encodable<S> for f32 {
- fn encode(&self, s: &mut S) {
- s.emit_f32(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for f32 {
- fn decode(d: &mut D) -> f32 {
- d.read_f32()
- }
-}
-
-impl<S:Encoder> Encodable<S> for f64 {
- fn encode(&self, s: &mut S) {
- s.emit_f64(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for f64 {
- fn decode(d: &mut D) -> f64 {
- d.read_f64()
- }
-}
-
-impl<S:Encoder> Encodable<S> for bool {
- fn encode(&self, s: &mut S) {
- s.emit_bool(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for bool {
- fn decode(d: &mut D) -> bool {
- d.read_bool()
- }
-}
-
-impl<S:Encoder> Encodable<S> for char {
- fn encode(&self, s: &mut S) {
- s.emit_char(*self)
- }
-}
-
-impl<D:Decoder> Decodable<D> for char {
- fn decode(d: &mut D) -> char {
- d.read_char()
- }
-}
-
-impl<S:Encoder> Encodable<S> for () {
- fn encode(&self, s: &mut S) {
- s.emit_nil()
- }
-}
-
-impl<D:Decoder> Decodable<D> for () {
- fn decode(d: &mut D) -> () {
- d.read_nil()
- }
-}
-
-impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> for &'a T {
- fn encode(&self, s: &mut S) {
- (**self).encode(s)
- }
-}
-
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~T {
- fn encode(&self, s: &mut S) {
- (**self).encode(s)
- }
-}
-
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~T {
- fn decode(d: &mut D) -> ~T {
- ~Decodable::decode(d)
- }
-}
-
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for @T {
- fn encode(&self, s: &mut S) {
- (**self).encode(s)
- }
-}
-
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for Rc<T> {
- #[inline]
- fn encode(&self, s: &mut S) {
- (**self).encode(s)
- }
-}
-
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for Rc<T> {
- #[inline]
- fn decode(d: &mut D) -> Rc<T> {
- Rc::new(Decodable::decode(d))
- }
-}
-
-impl<D:Decoder,T:Decodable<D> + 'static> Decodable<D> for @T {
- fn decode(d: &mut D) -> @T {
- @Decodable::decode(d)
- }
-}
-
-impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> 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<S:Encoder,T:Encodable<S>> Encodable<S> 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<D:Decoder,T:Decodable<D>> Decodable<D> 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<S:Encoder,T:Encodable<S>> Encodable<S> for Vec<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<D:Decoder,T:Decodable<D>> Decodable<D> for Vec<T> {
- fn decode(d: &mut D) -> Vec<T> {
- d.read_seq(|d, len| {
- Vec::from_fn(len, |i| {
- d.read_seq_elt(i, |d| Decodable::decode(d))
- })
- })
- }
-}
-
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> {
- 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<D:Decoder,T:Decodable<D>> Decodable<D> for Option<T> {
- fn decode(d: &mut D) -> Option<T> {
- d.read_option(|d, b| {
- if b {
- Some(Decodable::decode(d))
- } else {
- None
- }
- })
- }
-}
-
-impl<S:Encoder,T0:Encodable<S>,T1:Encodable<S>> Encodable<S> 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<D:Decoder,T0:Decodable<D>,T1:Decodable<D>> Decodable<D> 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<S>,
- T1: Encodable<S>,
- T2: Encodable<S>
-> Encodable<S> 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<D>,
- T1: Decodable<D>,
- T2: Decodable<D>
-> Decodable<D> 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<S>,
- T1: Encodable<S>,
- T2: Encodable<S>,
- T3: Encodable<S>
-> Encodable<S> 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<D>,
- T1: Decodable<D>,
- T2: Decodable<D>,
- T3: Decodable<D>
-> Decodable<D> 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<S>,
- T1: Encodable<S>,
- T2: Encodable<S>,
- T3: Encodable<S>,
- T4: Encodable<S>
-> Encodable<S> 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<D>,
- T1: Decodable<D>,
- T2: Decodable<D>,
- T3: Decodable<D>,
- T4: Decodable<D>
-> Decodable<D> 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<E: Encoder> Encodable<E> for path::posix::Path {
- fn encode(&self, e: &mut E) {
- self.as_vec().encode(e)
- }
-}
-
-impl<D: Decoder> Decodable<D> for path::posix::Path {
- fn decode(d: &mut D) -> path::posix::Path {
- let bytes: ~[u8] = Decodable::decode(d);
- path::posix::Path::new(bytes)
- }
-}
-
-impl<E: Encoder> Encodable<E> for path::windows::Path {
- fn encode(&self, e: &mut E) {
- self.as_vec().encode(e)
- }
-}
-
-impl<D: Decoder> Decodable<D> 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<T>(&mut self, v: &[T], f: |&mut Self, v: &T|);
-}
-
-impl<S:Encoder> EncoderHelpers for S {
- fn emit_from_vec<T>(&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<T>(&mut self, f: |&mut Self| -> T) -> ~[T];
-}
-
-impl<D:Decoder> DecoderHelpers for D {
- fn read_to_vec<T>(&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))
- })
- })
- }
-}
-
}
/// 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]
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 {}
}
/// 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.
/// 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.
/// A mark represents a unique id associated with a macro expansion
pub type Mrk = u32;
-// FIXME: remove stage0 Encodables after snapshot
-#[cfg(stage0)]
-impl<S: Encoder> Encodable<S> for Ident {
- fn encode(&self, s: &mut S) {
- s.emit_str(token::get_ident(*self).get());
- }
-}
-
-#[cfg(stage0)]
-impl<D:Decoder> Decodable<D> for Ident {
- fn decode(d: &mut D) -> Ident {
- str_to_ident(d.read_str())
- }
-}
-
-#[cfg(not(stage0))]
impl<S: Encoder<E>, E> Encodable<S, E> for Ident {
fn encode(&self, s: &mut S) -> Result<(), E> {
s.emit_str(token::get_ident(*self).get())
}
}
-#[cfg(not(stage0))]
impl<D:Decoder<E>, E> Decodable<D, E> for Ident {
fn decode(d: &mut D) -> Result<Ident, E> {
Ok(str_to_ident(try!(d.read_str())))
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<json::Encoder>;
- }
-
#[test]
- #[cfg(not(stage0))]
fn check_asts_encodable() {
use std::io;
let e = Crate {
impl TotalEq for Span {}
-// FIXME: remove stage0 Encodables/Decodables after snapshot
-#[cfg(stage0)]
-impl<S:Encoder> Encodable<S> for Span {
- /* Note #1972 -- spans are encoded but not decoded */
- fn encode(&self, s: &mut S) {
- s.emit_nil()
- }
-}
-
-#[cfg(stage0)]
-impl<D:Decoder> Decodable<D> for Span {
- fn decode(_d: &mut D) -> Span {
- DUMMY_SP
- }
-}
-
-#[cfg(not(stage0))]
impl<S:Encoder<E>, E> Encodable<S, E> for Span {
/* Note #1972 -- spans are encoded but not decoded */
fn encode(&self, s: &mut S) -> Result<(), E> {
}
}
-#[cfg(not(stage0))]
impl<D:Decoder<E>, E> Decodable<D, E> for Span {
fn decode(_d: &mut D) -> Result<Span, E> {
Ok(DUMMY_SP)
}
}
-// FIXME: remove stage0 Encodables/Decodables after snapshot
-#[cfg(stage0)]
-impl<S: Encoder, T: Encodable<S>> Encodable<S> for OwnedSlice<T> {
- fn encode(&self, s: &mut S) {
- self.as_slice().encode(s)
- }
-}
-
-#[cfg(stage0)]
-impl<D: Decoder, T: Decodable<D>> Decodable<D> for OwnedSlice<T> {
- fn decode(d: &mut D) -> OwnedSlice<T> {
- OwnedSlice::from_vec(Decodable::decode(d))
- }
-}
-
-#[cfg(not(stage0))]
impl<S: Encoder<E>, T: Encodable<S, E>, E> Encodable<S, E> for OwnedSlice<T> {
fn encode(&self, s: &mut S) -> Result<(), E> {
self.as_slice().encode(s)
}
}
-#[cfg(not(stage0))]
impl<D: Decoder<E>, T: Decodable<D, E>, E> Decodable<D, E> for OwnedSlice<T> {
fn decode(d: &mut D) -> Result<OwnedSlice<T>, E> {
Ok(OwnedSlice::from_vec(match Decodable::decode(d) {
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<json::Encoder<'a>>>(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<json::Encoder<'a>, io::IoError>>(val: &E) -> ~str {
let mut writer = MemWriter::new();
let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
}
}
-// FIXME: remove stage0 Encodables/Decodables after snapshot
-#[cfg(stage0)]
-impl<D:Decoder> Decodable<D> for InternedString {
- fn decode(d: &mut D) -> InternedString {
- get_name(get_ident_interner().intern(d.read_str()))
- }
-}
-
-#[cfg(stage0)]
-impl<E:Encoder> Encodable<E> for InternedString {
- fn encode(&self, e: &mut E) {
- e.emit_str(self.string.as_slice())
- }
-}
-
-#[cfg(not(stage0))]
impl<D:Decoder<E>, E> Decodable<D, E> for InternedString {
fn decode(d: &mut D) -> Result<InternedString, E> {
Ok(get_name(get_ident_interner().intern(try!(d.read_str()))))
}
}
-#[cfg(not(stage0))]
impl<S:Encoder<E>, E> Encodable<S, E> for InternedString {
fn encode(&self, s: &mut S) -> Result<(), E> {
s.emit_str(self.string.as_slice())
}
}
-// 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 {
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.
impl TotalEq for Uuid {}
// FIXME #9845: Test these more thoroughly
-// FIXME: remove stage0 Encodable/Decodable after snapshot
-#[cfg(stage0)]
-impl<T: Encoder> Encodable<T> 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<T: Decoder> Decodable<T> for Uuid {
- /// Decode a UUID from a string
- fn decode(d: &mut T) -> Uuid {
- from_str(d.read_str()).unwrap()
- }
-}
-
-#[cfg(not(stage0))]
impl<T: Encoder<E>, E> Encodable<T, E> for Uuid {
/// Encode a UUID as a hypenated string
fn encode(&self, e: &mut T) -> Result<(), E> {
}
}
-#[cfg(not(stage0))]
impl<T: Decoder<E>, E> Decodable<T, E> for Uuid {
/// Decode a UUID from a string
fn decode(d: &mut T) -> Result<Uuid, E> {
use std::str;
use std::io::MemWriter;
- // FIXME: remove unwrap_ after snapshot
- #[cfg(stage0)]
- fn unwrap_<T>(t: T) -> T {
- t
- }
-
- #[cfg(not(stage0))]
- fn unwrap_<T, E>(t: Result<T, E>) -> T {
- t.unwrap()
- }
-
#[test]
fn test_nil() {
let nil = Uuid::nil();
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);
}
+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