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
This commit is contained in:
Michael Neumann 2012-12-27 06:16:16 -06:00
parent 09bb07bed9
commit 2b6c456bf6
5 changed files with 12 additions and 10 deletions

View File

@ -360,7 +360,7 @@ fn read_rec<T>(&self, f: fn() -> T) -> T {
f()
}
fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
fn read_struct<T>(&self, name: &str, _len: uint, f: fn() -> T) -> T {
debug!("read_struct(name=%s)", name);
f()
}
@ -631,7 +631,7 @@ fn emit_vec_elt(&self, _idx: uint, f: fn()) {
}
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()

View File

@ -148,7 +148,7 @@ fn emit_rec(&self, f: fn()) {
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 @@ fn emit_rec(&self, f: fn()) {
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 @@ fn read_rec<T>(&self, f: fn() -> T) -> T {
move value
}
fn read_struct<T>(&self, _name: &str, f: fn() -> T) -> T {
fn read_struct<T>(&self, _name: &str, _len: uint, f: fn() -> T) -> T {
debug!("read_struct()");
let value = f();
self.pop();

View File

@ -160,7 +160,7 @@ fn emit_rec(&self, f: fn()) {
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(~"}");

View File

@ -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<T>(&self, idx: uint, f: fn() -> T) -> T;
fn read_rec<T>(&self, f: fn() -> T) -> T;
fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T;
fn read_struct<T>(&self, name: &str, _len: uint, f: fn() -> T) -> T;
fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T;
fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T;

View File

@ -25,7 +25,7 @@ struct Node {id: uint}
impl<S: Encoder> node_id: Encodable<S> {
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 @@ fn encode(s: &S) {
impl<D: Decoder> 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,