diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 72f5b528c9af..c28ad0a0282a 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -31,7 +31,7 @@ export uint, u8, u16, u32, u64; export float, f32, f64; export box, char, str, ptr, vec, bool; export either, option, result, iter; -export libc, os, io, run, rand, sys, unsafe, logging, serialization; +export libc, os, io, run, rand, sys, unsafe, logging; export comm, task, future; export extfmt; export tuple; @@ -88,7 +88,6 @@ mod cmath; mod sys; mod unsafe; mod logging; -mod serialization; // Concurrency mod comm; diff --git a/src/libcore/serialization.rs b/src/libcore/serialization.rs deleted file mode 100644 index 187be90c4f55..000000000000 --- a/src/libcore/serialization.rs +++ /dev/null @@ -1,116 +0,0 @@ -export serializer; -export serializer_helpers; -export deserializer; -export deserializer_helpers; - -/* -Core serialization interfaces. -*/ - -iface serializer { - // Primitive types: - fn emit_nil(); - fn emit_uint(v: uint); - fn emit_u64(v: u64); - fn emit_u32(v: u32); - fn emit_u16(v: u16); - fn emit_u8(v: u8); - fn emit_int(v: int); - fn emit_i64(v: i64); - fn emit_i32(v: i32); - fn emit_i16(v: i16); - fn emit_i8(v: i8); - fn emit_bool(v: bool); - fn emit_float(v: float); - fn emit_f64(v: f64); - fn emit_f32(v: f32); - fn emit_str(v: str); - - // Compound types: - fn emit_enum(name: str, f: fn()); - fn emit_enum_variant(v_name: str, v_id: uint, sz: uint, f: fn()); - fn emit_enum_variant_arg(idx: uint, f: fn()); - fn emit_vec(len: uint, f: fn()); - fn emit_vec_elt(idx: uint, f: fn()); - fn emit_box(f: fn()); - fn emit_uniq(f: fn()); - fn emit_rec(f: fn()); - fn emit_rec_field(f_name: str, f_idx: uint, f: fn()); - fn emit_tup(sz: uint, f: fn()); - fn emit_tup_elt(idx: uint, f: fn()); -} - -iface deserializer { - // Primitive types: - fn read_nil() -> (); - - fn read_uint() -> uint; - fn read_u64() -> u64; - fn read_u32() -> u32; - fn read_u16() -> u16; - fn read_u8() -> u8; - - fn read_int() -> int; - fn read_i64() -> i64; - fn read_i32() -> i32; - fn read_i16() -> i16; - fn read_i8() -> i8; - - - fn read_bool() -> bool; - - fn read_str() -> str; - - fn read_f64() -> f64; - fn read_f32() -> f32; - fn read_float() -> float; - - // Compound types: - fn read_enum(name: str, f: fn() -> T) -> T; - fn read_enum_variant(f: fn(uint) -> T) -> T; - fn read_enum_variant_arg(idx: uint, f: fn() -> T) -> T; - fn read_vec(f: fn(uint) -> T) -> T; - fn read_vec_elt(idx: uint, f: fn() -> T) -> T; - fn read_box(f: fn() -> T) -> T; - fn read_uniq(f: fn() -> T) -> T; - fn read_rec(f: fn() -> T) -> T; - fn read_rec_field(f_name: str, f_idx: uint, f: fn() -> T) -> T; - fn read_tup(sz: uint, f: fn() -> T) -> T; - fn read_tup_elt(idx: uint, f: fn() -> T) -> T; -} - -// ___________________________________________________________________________ -// Helper routines -// -// These should eventually be coded as traits. - -fn emit_from_vec(s: S, v: [T], f: fn(T)) { - s.emit_vec(vec::len(v)) {|| - vec::iteri(v) {|i,e| - s.emit_vec_elt(i) {|| - f(e) - } - } - } -} - -fn read_to_vec(d: D, f: fn() -> T) -> [T] { - d.read_vec {|len| - vec::from_fn(len) {|i| - d.read_vec_elt(i) {|| f() } - } - } -} - -impl serializer_helpers for S { - fn emit_from_vec(v: [T], f: fn(T)) { - emit_from_vec(self, v, f) - } -} - -impl deserializer_helpers for D { - fn read_to_vec(f: fn() -> T) -> [T] { - read_to_vec(self, f) - } -} - diff --git a/src/libcore/uint.rs b/src/libcore/uint.rs index e466717657d5..88230bea0940 100644 --- a/src/libcore/uint.rs +++ b/src/libcore/uint.rs @@ -192,14 +192,6 @@ fn compl(i: uint) -> uint { max_value ^ i } -fn serialize(s: S, v: uint) { - s.emit_uint(v); -} - -fn deserialize(d: D) -> uint { - d.read_uint() -} - #[cfg(test)] mod tests { diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 203e7e12ad03..2e08b51be16b 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -293,7 +293,7 @@ enum ebml_serializer_tag { es_label // Used only when debugging } -impl serializer of core::serialization::serializer for ebml::writer { +impl serializer of serialization::serializer for ebml::writer { fn emit_nil() {} // used internally to emit things like the vector length and so on @@ -371,7 +371,7 @@ fn ebml_deserializer(d: ebml::doc) -> ebml_deserializer { {mutable parent: d, mutable pos: d.start} } -impl deserializer of core::serialization::deserializer for ebml_deserializer { +impl deserializer of serialization::deserializer for ebml_deserializer { fn _check_label(lbl: str) { if self.pos < self.parent.end { let {tag: r_tag, doc: r_doc} = diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index c0f71d067c4d..64208c0af48e 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -1,12 +1,122 @@ -#[doc = "Support code for serialization. - -Deprecated in favor of core::serialization."]; +#[doc = "Support code for serialization."]; use core; -import list::list; -import ebml::writer; -import core::serialization::{serializer,deserializer}; +/* +Core serialization interfaces. +*/ -export serializer; -export deserializer; +iface serializer { + // Primitive types: + fn emit_nil(); + fn emit_uint(v: uint); + fn emit_u64(v: u64); + fn emit_u32(v: u32); + fn emit_u16(v: u16); + fn emit_u8(v: u8); + fn emit_int(v: int); + fn emit_i64(v: i64); + fn emit_i32(v: i32); + fn emit_i16(v: i16); + fn emit_i8(v: i8); + fn emit_bool(v: bool); + fn emit_float(v: float); + fn emit_f64(v: f64); + fn emit_f32(v: f32); + fn emit_str(v: str); + + // Compound types: + fn emit_enum(name: str, f: fn()); + fn emit_enum_variant(v_name: str, v_id: uint, sz: uint, f: fn()); + fn emit_enum_variant_arg(idx: uint, f: fn()); + fn emit_vec(len: uint, f: fn()); + fn emit_vec_elt(idx: uint, f: fn()); + fn emit_box(f: fn()); + fn emit_uniq(f: fn()); + fn emit_rec(f: fn()); + fn emit_rec_field(f_name: str, f_idx: uint, f: fn()); + fn emit_tup(sz: uint, f: fn()); + fn emit_tup_elt(idx: uint, f: fn()); +} + +iface deserializer { + // Primitive types: + fn read_nil() -> (); + + fn read_uint() -> uint; + fn read_u64() -> u64; + fn read_u32() -> u32; + fn read_u16() -> u16; + fn read_u8() -> u8; + + fn read_int() -> int; + fn read_i64() -> i64; + fn read_i32() -> i32; + fn read_i16() -> i16; + fn read_i8() -> i8; + + + fn read_bool() -> bool; + + fn read_str() -> str; + + fn read_f64() -> f64; + fn read_f32() -> f32; + fn read_float() -> float; + + // Compound types: + fn read_enum(name: str, f: fn() -> T) -> T; + fn read_enum_variant(f: fn(uint) -> T) -> T; + fn read_enum_variant_arg(idx: uint, f: fn() -> T) -> T; + fn read_vec(f: fn(uint) -> T) -> T; + fn read_vec_elt(idx: uint, f: fn() -> T) -> T; + fn read_box(f: fn() -> T) -> T; + fn read_uniq(f: fn() -> T) -> T; + fn read_rec(f: fn() -> T) -> T; + fn read_rec_field(f_name: str, f_idx: uint, f: fn() -> T) -> T; + fn read_tup(sz: uint, f: fn() -> T) -> T; + fn read_tup_elt(idx: uint, f: fn() -> T) -> T; +} + +// ___________________________________________________________________________ +// Helper routines +// +// In some cases, these should eventually be coded as traits. + +fn emit_from_vec(s: S, v: [T], f: fn(T)) { + s.emit_vec(vec::len(v)) {|| + vec::iteri(v) {|i,e| + s.emit_vec_elt(i) {|| + f(e) + } + } + } +} + +fn read_to_vec(d: D, f: fn() -> T) -> [T] { + d.read_vec {|len| + vec::from_fn(len) {|i| + d.read_vec_elt(i) {|| f() } + } + } +} + +impl serializer_helpers for S { + fn emit_from_vec(v: [T], f: fn(T)) { + emit_from_vec(self, v, f) + } +} + +impl deserializer_helpers for D { + fn read_to_vec(f: fn() -> T) -> [T] { + read_to_vec(self, f) + } +} + +fn serialize_uint(s: S, v: uint) { + s.emit_uint(v); +} + +fn deserialize_uint(d: D) -> uint { + d.read_uint() +} diff --git a/src/rustc/metadata/astencode.rs b/src/rustc/metadata/astencode.rs index 4aea919c40f5..aa3fd0766273 100644 --- a/src/rustc/metadata/astencode.rs +++ b/src/rustc/metadata/astencode.rs @@ -9,10 +9,10 @@ import std::ebml::writer; import std::ebml::serializer; import std::ebml::deserializer; import std::map::hashmap; -import serialization::serializer; -import serialization::deserializer; -import serialization::serializer_helpers; -import serialization::deserializer_helpers; +import std::serialization::serializer; +import std::serialization::deserializer; +import std::serialization::serializer_helpers; +import std::serialization::deserializer_helpers; import std::smallintmap::map; import middle::trans::common::maps; import middle::{ty, typeck, last_use, ast_map}; @@ -295,13 +295,13 @@ impl of tr for span { } } -impl serializer_helpers for S { +impl serializer_helpers for S { fn emit_def_id(did: ast::def_id) { astencode_gen::serialize_syntax_ast_def_id(self, did) } } -impl deserializer_helpers for D { +impl deserializer_helpers for D { fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id { let did = astencode_gen::deserialize_syntax_ast_def_id(self); did.tr(xcx) diff --git a/src/rustc/syntax/ext/auto_serialize.rs b/src/rustc/syntax/ext/auto_serialize.rs index 1b048c262401..698b962eba7d 100644 --- a/src/rustc/syntax/ext/auto_serialize.rs +++ b/src/rustc/syntax/ext/auto_serialize.rs @@ -9,18 +9,13 @@ For example, a type like: type node_id = uint; -would generate a companion module like: +would generate two functions like: - mod node_id { - use std; - import std::serialization::serializer; - import std::serialization::deserializer; - fn serialize(s: S, v: node_id) { - s.emit_uint(v); - } - fn deserializer(d: D) -> node_id { - d.read_uint() - } + fn serialize_node_id(s: S, v: node_id) { + s.emit_uint(v); + } + fn deserialize_node_id(d: D) -> node_id { + d.read_uint() } Other interesting scenarios are whe the item has type parameters or @@ -28,34 +23,29 @@ references other non-built-in types. A type definition like: type spanned = {node: T, span: span}; -would yield a helper module like: +would yield functions like: - mod spanned { - use std; - import std::serialization::serializer; - import std::serialization::deserializer; - fn serialize(s: S, t: fn(T), v: spanned) { - s.emit_rec(2u) {|| - s.emit_rec_field("node", 0u) {|| - t(s.node); - }; - s.emit_rec_field("span", 1u) {|| - span::serialize(s, s.span); - }; - } - } - fn deserializer(d: D, t: fn() -> T) -> node_id { - d.read_rec(2u) {|| - {node: d.read_rec_field("node", 0u, t), - span: d.read_rec_field("span", 1u) {||span::deserialize(d)}} - } - } + fn serialize_spanned(s: S, v: spanned, t: fn(T)) { + s.emit_rec(2u) {|| + s.emit_rec_field("node", 0u) {|| + t(s.node); + }; + s.emit_rec_field("span", 1u) {|| + serialize_span(s, s.span); + }; + } + } + fn deserialize_spanned(d: D, t: fn() -> T) -> node_id { + d.read_rec(2u) {|| + {node: d.read_rec_field("node", 0u, t), + span: d.read_rec_field("span", 1u) {||deserialize_span(d)}} + } } In general, the code to serialize an instance `v` of a non-built-in type a::b::c looks like: - a::b::c::serialize(s, {|v| c_T0}, ..., {|v| c_Tn}, v) + a::b::serialize_c(s, {|v| c_T0}, ..., {|v| c_Tn}, v) where `c_Ti` is the code to serialize an instance `v` of the type `Ti`. @@ -63,12 +53,13 @@ where `c_Ti` is the code to serialize an instance `v` of the type Similarly, the code to deserialize an instance of a non-built-in type `a::b::c` using the deserializer `d` looks like: - a::b::c::deserialize(d, {|| c_T0}, ..., {|| c_Tn}) + a::b::deserialize_c(d, {|| c_T0}, ..., {|| c_Tn}) where `c_Ti` is the code to deserialize an instance of `Ti` using the deserializer `d`. -TODO--Hygiene. Search for "__" strings. +TODO--Hygiene. Search for "__" strings. We also assume "std" is the +standard library. Misc notes: ----------- @@ -106,13 +97,12 @@ fn expand(cx: ext_ctxt, vec::flat_map(in_items) {|in_item| alt in_item.node { ast::item_ty(ty, tps) { - [filter_attrs(in_item), - ty_module(cx, in_item.ident, ty, tps)] + [filter_attrs(in_item)] + ty_fns(cx, in_item.ident, ty, tps) } ast::item_enum(variants, tps) { - [filter_attrs(in_item), - enum_module(cx, in_item.ident, in_item.span, variants, tps)] + [filter_attrs(in_item)] + enum_fns(cx, in_item.ident, + in_item.span, variants, tps) } _ { @@ -128,6 +118,13 @@ fn expand(cx: ext_ctxt, impl helpers for ext_ctxt { fn next_id() -> ast::node_id { self.session().next_node_id() } + fn helper_path(base_path: @ast::path, + helper_name: str) -> @ast::path { + let head = vec::init(base_path.node.idents); + let tail = vec::last(base_path.node.idents); + self.path(base_path.span, head + [helper_name + "_" + tail]) + } + fn path(span: span, strs: [str]) -> @ast::path { @{node: {global: false, idents: strs, types: []}, span: span} @@ -284,7 +281,7 @@ fn ser_path(cx: ext_ctxt, tps: ser_tps_map, path: @ast::path, cx.expr( path.span, ast::expr_path( - cx.path(path.span, path.node.idents + ["serialize"]))); + cx.helper_path(path, "serialize"))); let ty_args = vec::map(path.node.types) {|ty| let sv_stmts = ser_ty(cx, tps, ty, cx.clone(s), #ast{ __v }); @@ -466,13 +463,13 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map, cx.at(ty.span, #ast{ __e }))))); [#ast(stmt){ - core::serialization::emit_from_vec($(s), $(v), {|__e| $(ser_e) }) + std::serialization::emit_from_vec($(s), $(v), {|__e| $(ser_e) }) }] } } } -fn mk_ser_fn(cx: ext_ctxt, span: span, +fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, -v_ty: @ast::ty, tps: [ast::ty_param], f: fn(ext_ctxt, ser_tps_map, @ast::ty, -@ast::expr, -@ast::expr) -> [@ast::stmt]) @@ -514,7 +511,8 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, } let ser_bnds = @[ast::bound_iface(cx.ty_path(span, - ["serialization", + ["std", + "serialization", "serializer"]))]; let ser_tps: [ast::ty_param] = @@ -530,7 +528,7 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, let ser_blk = cx.blk(span, f(cx, tps_map, v_ty, #ast{ __s }, #ast{ __v })); - @{ident: "serialize", + @{ident: "serialize_" + name, attrs: [], id: cx.next_id(), node: ast::item_fn({inputs: ser_inputs, @@ -554,7 +552,7 @@ fn deser_path(cx: ext_ctxt, tps: deser_tps_map, path: @ast::path, cx.expr( path.span, ast::expr_path( - cx.path(path.span, path.node.idents + ["deserialize"]))); + cx.helper_path(path, "deserialize"))); let ty_args = vec::map(path.node.types) {|ty| let dv_expr = deser_ty(cx, tps, ty, cx.clone(d)); @@ -667,12 +665,12 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map, ast::ty_vec(mt) { let l = deser_lambda(cx, tps, mt.ty, cx.clone(d)); - #ast{ core::serialization::read_to_vec($(d), $(l)) } + #ast{ std::serialization::read_to_vec($(d), $(l)) } } } } -fn mk_deser_fn(cx: ext_ctxt, span: span, +fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, -v_ty: @ast::ty, tps: [ast::ty_param], f: fn(ext_ctxt, deser_tps_map, @ast::ty, -@ast::expr) -> @ast::expr) @@ -709,7 +707,8 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, } let deser_bnds = @[ast::bound_iface(cx.ty_path(span, - ["serialization", + ["std", + "serialization", "deserializer"]))]; let deser_tps: [ast::ty_param] = @@ -720,7 +719,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, let deser_blk = cx.expr_blk(f(cx, tps_map, v_ty, #ast(expr){__d})); - @{ident: "deserialize", + @{ident: "deserialize_" + name, attrs: [], id: cx.next_id(), node: ast::item_fn({inputs: deser_inputs, @@ -733,21 +732,14 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, span: span} } -fn ty_module(cx: ext_ctxt, name: str, ty: @ast::ty, tps: [ast::ty_param]) - -> @ast::item { +fn ty_fns(cx: ext_ctxt, name: str, ty: @ast::ty, tps: [ast::ty_param]) + -> [@ast::item] { let span = ty.span; - let ser_fn = mk_ser_fn(cx, span, cx.clone_ty(ty), tps, ser_ty); - let deser_fn = mk_deser_fn(cx, span, cx.clone_ty(ty), tps, deser_ty); - - // Return a module containing the serialization and deserialization - // functions: - @{ident: name, - attrs: [], - id: cx.next_id(), - node: ast::item_mod({view_items: [], - items: [ser_fn, deser_fn]}), - span: span} + [ + mk_ser_fn(cx, span, name, cx.clone_ty(ty), tps, ser_ty), + mk_deser_fn(cx, span, name, cx.clone_ty(ty), tps, deser_ty) + ] } fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: str, @@ -836,21 +828,14 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: str, #ast{ $(d).read_enum($(e_name), $(read_lambda)) } } -fn enum_module(cx: ext_ctxt, e_name: str, e_span: span, +fn enum_fns(cx: ext_ctxt, e_name: str, e_span: span, variants: [ast::variant], tps: [ast::ty_param]) - -> @ast::item { + -> [@ast::item] { let ty = cx.ty_path(e_span, [e_name]); - let ser_fn = - mk_ser_fn(cx, e_span, cx.clone_ty(ty), tps, - ser_enum(_, _, e_name, e_span, variants, _, _, _)); - let deser_fn = - mk_deser_fn(cx, e_span, ty, tps, - deser_enum(_, _, e_name, e_span, variants, _, _)); - - @{ident: e_name, - attrs: [], - id: cx.next_id(), - node: ast::item_mod({view_items: [], - items: [ser_fn, deser_fn]}), - span: e_span} + [ + mk_ser_fn(cx, e_span, e_name, cx.clone_ty(ty), tps, + ser_enum(_, _, e_name, e_span, variants, _, _, _)), + mk_deser_fn(cx, e_span, e_name, ty, tps, + deser_enum(_, _, e_name, e_span, variants, _, _)) + ] } diff --git a/src/test/run-pass/auto_serialize.rs b/src/test/run-pass/auto_serialize.rs index d2d7eaa5ac49..72e8cc238c20 100644 --- a/src/test/run-pass/auto_serialize.rs +++ b/src/test/run-pass/auto_serialize.rs @@ -8,6 +8,7 @@ import io::writer; import std::prettyprint::serializer; import std::ebml::serializer; import std::ebml::deserializer; +import std::serialization::{serialize_uint, deserialize_uint}; fn test_ser_and_deser(a1: A, expected: str, @@ -68,31 +69,31 @@ fn main() { @plus(@val(22u), @val(5u))), "plus(@minus(@val(3u), @val(10u)), \ @plus(@val(22u), @val(5u)))", - expr::serialize(_, _), - expr::deserialize(_), - expr::serialize(_, _)); + serialize_expr(_, _), + deserialize_expr(_), + serialize_expr(_, _)); test_ser_and_deser({lo: 0u, hi: 5u, node: 22u}, "{lo: 0u, hi: 5u, node: 22u}", - spanned_uint::serialize(_, _), - spanned_uint::deserialize(_), - spanned_uint::serialize(_, _)); + serialize_spanned_uint(_, _), + deserialize_spanned_uint(_), + serialize_spanned_uint(_, _)); test_ser_and_deser(an_enum({v: [1u, 2u, 3u]}), "an_enum({v: [1u, 2u, 3u]})", - an_enum::serialize(_, _), - an_enum::deserialize(_), - an_enum::serialize(_, _)); + serialize_an_enum(_, _), + deserialize_an_enum(_), + serialize_an_enum(_, _)); test_ser_and_deser({x: 3u, y: 5u}, "{x: 3u, y: 5u}", - point::serialize(_, _), - point::deserialize(_), - point::serialize(_, _)); + serialize_point(_, _), + deserialize_point(_), + serialize_point(_, _)); test_ser_and_deser([1u, 2u, 3u], "[1u, 2u, 3u]", - uint_vec::serialize(_, _), - uint_vec::deserialize(_), - uint_vec::serialize(_, _)); + serialize_uint_vec(_, _), + deserialize_uint_vec(_), + serialize_uint_vec(_, _)); } \ No newline at end of file