From 2b6c456bf648e5a7b408b550649d409378e39539 Mon Sep 17 00:00:00 2001 From: Michael Neumann Date: Thu, 27 Dec 2012 06:16:16 -0600 Subject: [PATCH] Enhance auto_encode to take number of struct fields emit_struct and read_struct takes an additional len:uint parameter which tells us how many fields the struct we are working on has. This is required to implement an Encoder for the msgpack [1] serialization format. To serialize a struct with msgpack you have to use arrays and the size of the array has to be know before each of the elements are written out. JSON as an example doesn't have this problem as it uses '[' and ']' delimiters for arrays. [1]: www.msgpack.org --- src/libstd/ebml.rs | 4 ++-- src/libstd/json.rs | 6 +++--- src/libstd/prettyprint.rs | 2 +- src/libstd/serialize.rs | 4 ++-- src/libsyntax/ext/auto_encode.rs | 6 ++++-- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 59e0a1e84fe8f..f782b6ff6a7bd 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -360,7 +360,7 @@ pub mod reader { f() } - fn read_struct(&self, name: &str, f: fn() -> T) -> T { + fn read_struct(&self, name: &str, _len: uint, f: fn() -> T) -> T { debug!("read_struct(name=%s)", name); f() } @@ -631,7 +631,7 @@ pub mod writer { } fn emit_rec(&self, f: fn()) { f() } - fn emit_struct(&self, _name: &str, f: fn()) { f() } + fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { f() } fn emit_field(&self, name: &str, _idx: uint, f: fn()) { self._emit_label(name); f() diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 770d621d51fc7..1d46a54518589 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -148,7 +148,7 @@ pub impl Encoder: serialize::Encoder { f(); self.wr.write_char('}'); } - fn emit_struct(&self, _name: &str, f: fn()) { + fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { self.wr.write_char('{'); f(); self.wr.write_char('}'); @@ -261,7 +261,7 @@ pub impl PrettyEncoder: serialize::Encoder { self.indent -= 2; self.wr.write_char('}'); } - fn emit_struct(&self, _name: &str, f: fn()) { + fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { self.emit_rec(f) } fn emit_field(&self, name: &str, idx: uint, f: fn()) { @@ -861,7 +861,7 @@ pub impl Decoder: serialize::Decoder { move value } - fn read_struct(&self, _name: &str, f: fn() -> T) -> T { + fn read_struct(&self, _name: &str, _len: uint, f: fn() -> T) -> T { debug!("read_struct()"); let value = f(); self.pop(); diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index ef26a8cb19035..5e477042b6be2 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -160,7 +160,7 @@ pub impl Encoder: serialize::Encoder { self.wr.write_str(~"}"); } - fn emit_struct(&self, name: &str, f: fn()) { + fn emit_struct(&self, name: &str, _len: uint, f: fn()) { self.wr.write_str(fmt!("%s {", name)); f(); self.wr.write_str(~"}"); diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs index 9b1949256931c..a08d8defd5ce6 100644 --- a/src/libstd/serialize.rs +++ b/src/libstd/serialize.rs @@ -54,7 +54,7 @@ pub trait Encoder { fn emit_vec_elt(&self, idx: uint, f: fn()); fn emit_rec(&self, f: fn()); - fn emit_struct(&self, name: &str, f: fn()); + fn emit_struct(&self, name: &str, _len: uint, f: fn()); fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); fn emit_tup(&self, len: uint, f: fn()); @@ -95,7 +95,7 @@ pub trait Decoder { fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T; fn read_rec(&self, f: fn() -> T) -> T; - fn read_struct(&self, name: &str, f: fn() -> T) -> T; + fn read_struct(&self, name: &str, _len: uint, f: fn() -> T) -> T; fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T; fn read_tup(&self, sz: uint, f: fn() -> T) -> T; diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 8eb37386364f4..680fa169afe79 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -25,7 +25,7 @@ would generate two implementations like: impl node_id: Encodable { fn encode(s: &S) { - do s.emit_struct("Node") { + do s.emit_struct("Node", 1) { s.emit_field("id", 0, || s.emit_uint(self)) } } @@ -33,7 +33,7 @@ would generate two implementations like: impl node_id: Decodable { static fn decode(d: &D) -> Node { - do d.read_struct("Node") { + do d.read_struct("Node", 1) { Node { id: d.read_field(~"x", 0, || decode(d)) } @@ -686,6 +686,7 @@ fn mk_struct_ser_impl( ), ~[ cx.lit_str(span, @cx.str_of(ident)), + cx.lit_uint(span, vec::len(fields)), cx.lambda_stmts(span, fields), ] ); @@ -712,6 +713,7 @@ fn mk_struct_deser_impl( ), ~[ cx.lit_str(span, @cx.str_of(ident)), + cx.lit_uint(span, vec::len(fields)), cx.lambda_expr( cx.expr( span,