Add deserializable and more types to serialization2
This commit is contained in:
parent
0a950f394d
commit
81423a3866
7 changed files with 590 additions and 275 deletions
|
@ -384,7 +384,25 @@ impl Serializer: serialization2::Serializer {
|
||||||
fail ~"Unimplemented: serializing a float";
|
fail ~"Unimplemented: serializing a float";
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_str(&self, v: &str) { self.wr_tagged_str(EsStr as uint, v) }
|
fn emit_char(&self, _v: char) {
|
||||||
|
fail ~"Unimplemented: serializing a char";
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_borrowed_str(&self, v: &str) {
|
||||||
|
self.wr_tagged_str(EsStr as uint, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_owned_str(&self, v: &str) {
|
||||||
|
self.emit_borrowed_str(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_managed_str(&self, v: &str) {
|
||||||
|
self.emit_borrowed_str(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_borrowed(&self, f: fn()) { f() }
|
||||||
|
fn emit_owned(&self, f: fn()) { f() }
|
||||||
|
fn emit_managed(&self, f: fn()) { f() }
|
||||||
|
|
||||||
fn emit_enum(&self, name: &str, f: fn()) {
|
fn emit_enum(&self, name: &str, f: fn()) {
|
||||||
self._emit_label(name);
|
self._emit_label(name);
|
||||||
|
@ -397,25 +415,33 @@ impl Serializer: serialization2::Serializer {
|
||||||
}
|
}
|
||||||
fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
|
fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
|
||||||
|
|
||||||
fn emit_vec(&self, len: uint, f: fn()) {
|
fn emit_borrowed_vec(&self, len: uint, f: fn()) {
|
||||||
do self.wr_tag(EsVec as uint) {
|
do self.wr_tag(EsVec as uint) {
|
||||||
self._emit_tagged_uint(EsVecLen, len);
|
self._emit_tagged_uint(EsVecLen, len);
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_owned_vec(&self, len: uint, f: fn()) {
|
||||||
|
self.emit_borrowed_vec(len, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_managed_vec(&self, len: uint, f: fn()) {
|
||||||
|
self.emit_borrowed_vec(len, f)
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_vec_elt(&self, _idx: uint, f: fn()) {
|
fn emit_vec_elt(&self, _idx: uint, f: fn()) {
|
||||||
self.wr_tag(EsVecElt as uint, f)
|
self.wr_tag(EsVecElt as uint, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_box(&self, f: fn()) { f() }
|
|
||||||
fn emit_uniq(&self, f: fn()) { f() }
|
|
||||||
fn emit_rec(&self, f: fn()) { f() }
|
fn emit_rec(&self, f: fn()) { f() }
|
||||||
fn emit_rec_field(&self, f_name: &str, _f_idx: uint, f: fn()) {
|
fn emit_struct(&self, _name: &str, f: fn()) { f() }
|
||||||
self._emit_label(f_name);
|
fn emit_field(&self, name: &str, _idx: uint, f: fn()) {
|
||||||
|
self._emit_label(name);
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
fn emit_tup(&self, _sz: uint, f: fn()) { f() }
|
|
||||||
|
fn emit_tup(&self, _len: uint, f: fn()) { f() }
|
||||||
fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
|
fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,9 +551,22 @@ impl Deserializer: serialization2::Deserializer {
|
||||||
fn read_f32(&self) -> f32 { fail ~"read_f32()"; }
|
fn read_f32(&self) -> f32 { fail ~"read_f32()"; }
|
||||||
fn read_float(&self) -> float { fail ~"read_float()"; }
|
fn read_float(&self) -> float { fail ~"read_float()"; }
|
||||||
|
|
||||||
fn read_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
|
fn read_char(&self) -> char { fail ~"read_char()"; }
|
||||||
|
|
||||||
|
fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
|
||||||
|
fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; }
|
||||||
|
|
||||||
// Compound types:
|
// Compound types:
|
||||||
|
fn read_owned<T>(&self, f: fn() -> T) -> T {
|
||||||
|
debug!("read_owned()");
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_managed<T>(&self, f: fn() -> T) -> T {
|
||||||
|
debug!("read_managed()");
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
|
fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
|
||||||
debug!("read_enum(%s)", name);
|
debug!("read_enum(%s)", name);
|
||||||
self._check_label(name);
|
self._check_label(name);
|
||||||
|
@ -548,8 +587,17 @@ impl Deserializer: serialization2::Deserializer {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_vec<T>(&self, f: fn(uint) -> T) -> T {
|
fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
|
||||||
debug!("read_vec()");
|
debug!("read_owned_vec()");
|
||||||
|
do self.push_doc(self.next_doc(EsVec)) {
|
||||||
|
let len = self._next_uint(EsVecLen);
|
||||||
|
debug!(" len=%u", len);
|
||||||
|
f(len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
|
||||||
|
debug!("read_managed_vec()");
|
||||||
do self.push_doc(self.next_doc(EsVec)) {
|
do self.push_doc(self.next_doc(EsVec)) {
|
||||||
let len = self._next_uint(EsVecLen);
|
let len = self._next_uint(EsVecLen);
|
||||||
debug!(" len=%u", len);
|
debug!(" len=%u", len);
|
||||||
|
@ -562,30 +610,24 @@ impl Deserializer: serialization2::Deserializer {
|
||||||
self.push_doc(self.next_doc(EsVecElt), f)
|
self.push_doc(self.next_doc(EsVecElt), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_box<T>(&self, f: fn() -> T) -> T {
|
|
||||||
debug!("read_box()");
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_uniq<T>(&self, f: fn() -> T) -> T {
|
|
||||||
debug!("read_uniq()");
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_rec<T>(&self, f: fn() -> T) -> T {
|
fn read_rec<T>(&self, f: fn() -> T) -> T {
|
||||||
debug!("read_rec()");
|
debug!("read_rec()");
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_rec_field<T>(&self, f_name: &str, f_idx: uint,
|
fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
|
||||||
f: fn() -> T) -> T {
|
debug!("read_struct(name=%s)", name);
|
||||||
debug!("read_rec_field(%s, idx=%u)", f_name, f_idx);
|
|
||||||
self._check_label(f_name);
|
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T {
|
fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
|
||||||
debug!("read_tup(sz=%u)", sz);
|
debug!("read_field(name=%s, idx=%u)", name, idx);
|
||||||
|
self._check_label(name);
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
|
||||||
|
debug!("read_tup(len=%u)", len);
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,7 +637,6 @@ impl Deserializer: serialization2::Deserializer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ___________________________________________________________________________
|
// ___________________________________________________________________________
|
||||||
// Testing
|
// Testing
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,15 @@ pub impl Serializer: serialization2::Serializer {
|
||||||
self.wr.write_str(float::to_str(v, 6u));
|
self.wr.write_str(float::to_str(v, 6u));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_str(&self, v: &str) {
|
fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
|
||||||
let s = escape_str(v);
|
|
||||||
self.wr.write_str(s);
|
fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)) }
|
||||||
}
|
fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
|
||||||
|
fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
|
||||||
|
|
||||||
|
fn emit_borrowed(&self, f: fn()) { f() }
|
||||||
|
fn emit_owned(&self, f: fn()) { f() }
|
||||||
|
fn emit_managed(&self, f: fn()) { f() }
|
||||||
|
|
||||||
fn emit_enum(&self, name: &str, f: fn()) {
|
fn emit_enum(&self, name: &str, f: fn()) {
|
||||||
if name != "option" { fail ~"only supports option enum" }
|
if name != "option" { fail ~"only supports option enum" }
|
||||||
|
@ -112,32 +117,41 @@ pub impl Serializer: serialization2::Serializer {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_vec(&self, _len: uint, f: fn()) {
|
fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
|
||||||
self.wr.write_char('[');
|
self.wr.write_char('[');
|
||||||
f();
|
f();
|
||||||
self.wr.write_char(']');
|
self.wr.write_char(']');
|
||||||
}
|
}
|
||||||
|
fn emit_owned_vec(&self, len: uint, f: fn()) {
|
||||||
|
self.emit_borrowed_vec(len, f)
|
||||||
|
}
|
||||||
|
fn emit_managed_vec(&self, len: uint, f: fn()) {
|
||||||
|
self.emit_borrowed_vec(len, f)
|
||||||
|
}
|
||||||
fn emit_vec_elt(&self, idx: uint, f: fn()) {
|
fn emit_vec_elt(&self, idx: uint, f: fn()) {
|
||||||
if idx != 0 { self.wr.write_char(','); }
|
if idx != 0 { self.wr.write_char(','); }
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_box(&self, f: fn()) { f() }
|
|
||||||
fn emit_uniq(&self, f: fn()) { f() }
|
|
||||||
fn emit_rec(&self, f: fn()) {
|
fn emit_rec(&self, f: fn()) {
|
||||||
self.wr.write_char('{');
|
self.wr.write_char('{');
|
||||||
f();
|
f();
|
||||||
self.wr.write_char('}');
|
self.wr.write_char('}');
|
||||||
}
|
}
|
||||||
fn emit_rec_field(&self, name: &str, idx: uint, f: fn()) {
|
fn emit_struct(&self, _name: &str, f: fn()) {
|
||||||
|
self.wr.write_char('{');
|
||||||
|
f();
|
||||||
|
self.wr.write_char('}');
|
||||||
|
}
|
||||||
|
fn emit_field(&self, name: &str, idx: uint, f: fn()) {
|
||||||
if idx != 0 { self.wr.write_char(','); }
|
if idx != 0 { self.wr.write_char(','); }
|
||||||
self.wr.write_str(escape_str(name));
|
self.wr.write_str(escape_str(name));
|
||||||
self.wr.write_char(':');
|
self.wr.write_char(':');
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
fn emit_tup(&self, sz: uint, f: fn()) {
|
|
||||||
self.emit_vec(sz, f);
|
fn emit_tup(&self, len: uint, f: fn()) {
|
||||||
|
self.emit_borrowed_vec(len, f);
|
||||||
}
|
}
|
||||||
fn emit_tup_elt(&self, idx: uint, f: fn()) {
|
fn emit_tup_elt(&self, idx: uint, f: fn()) {
|
||||||
self.emit_vec_elt(idx, f)
|
self.emit_vec_elt(idx, f)
|
||||||
|
@ -182,7 +196,15 @@ pub impl PrettySerializer: serialization2::Serializer {
|
||||||
self.wr.write_str(float::to_str(v, 6u));
|
self.wr.write_str(float::to_str(v, 6u));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
|
fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
|
||||||
|
|
||||||
|
fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
|
||||||
|
fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
|
||||||
|
fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
|
||||||
|
|
||||||
|
fn emit_borrowed(&self, f: fn()) { f() }
|
||||||
|
fn emit_owned(&self, f: fn()) { f() }
|
||||||
|
fn emit_managed(&self, f: fn()) { f() }
|
||||||
|
|
||||||
fn emit_enum(&self, name: &str, f: fn()) {
|
fn emit_enum(&self, name: &str, f: fn()) {
|
||||||
if name != "option" { fail ~"only supports option enum" }
|
if name != "option" { fail ~"only supports option enum" }
|
||||||
|
@ -199,14 +221,19 @@ pub impl PrettySerializer: serialization2::Serializer {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_vec(&self, _len: uint, f: fn()) {
|
fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
|
||||||
self.wr.write_char('[');
|
self.wr.write_char('[');
|
||||||
self.indent += 2;
|
self.indent += 2;
|
||||||
f();
|
f();
|
||||||
self.indent -= 2;
|
self.indent -= 2;
|
||||||
self.wr.write_char(']');
|
self.wr.write_char(']');
|
||||||
}
|
}
|
||||||
|
fn emit_owned_vec(&self, len: uint, f: fn()) {
|
||||||
|
self.emit_borrowed_vec(len, f)
|
||||||
|
}
|
||||||
|
fn emit_managed_vec(&self, len: uint, f: fn()) {
|
||||||
|
self.emit_borrowed_vec(len, f)
|
||||||
|
}
|
||||||
fn emit_vec_elt(&self, idx: uint, f: fn()) {
|
fn emit_vec_elt(&self, idx: uint, f: fn()) {
|
||||||
if idx == 0 {
|
if idx == 0 {
|
||||||
self.wr.write_char('\n');
|
self.wr.write_char('\n');
|
||||||
|
@ -217,8 +244,6 @@ pub impl PrettySerializer: serialization2::Serializer {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_box(&self, f: fn()) { f() }
|
|
||||||
fn emit_uniq(&self, f: fn()) { f() }
|
|
||||||
fn emit_rec(&self, f: fn()) {
|
fn emit_rec(&self, f: fn()) {
|
||||||
self.wr.write_char('{');
|
self.wr.write_char('{');
|
||||||
self.indent += 2;
|
self.indent += 2;
|
||||||
|
@ -226,7 +251,10 @@ pub impl PrettySerializer: serialization2::Serializer {
|
||||||
self.indent -= 2;
|
self.indent -= 2;
|
||||||
self.wr.write_char('}');
|
self.wr.write_char('}');
|
||||||
}
|
}
|
||||||
fn emit_rec_field(&self, name: &str, idx: uint, f: fn()) {
|
fn emit_struct(&self, _name: &str, f: fn()) {
|
||||||
|
self.emit_rec(f)
|
||||||
|
}
|
||||||
|
fn emit_field(&self, name: &str, idx: uint, f: fn()) {
|
||||||
if idx == 0 {
|
if idx == 0 {
|
||||||
self.wr.write_char('\n');
|
self.wr.write_char('\n');
|
||||||
} else {
|
} else {
|
||||||
|
@ -238,43 +266,39 @@ pub impl PrettySerializer: serialization2::Serializer {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
fn emit_tup(&self, sz: uint, f: fn()) {
|
fn emit_tup(&self, sz: uint, f: fn()) {
|
||||||
self.emit_vec(sz, f);
|
self.emit_borrowed_vec(sz, f);
|
||||||
}
|
}
|
||||||
fn emit_tup_elt(&self, idx: uint, f: fn()) {
|
fn emit_tup_elt(&self, idx: uint, f: fn()) {
|
||||||
self.emit_vec_elt(idx, f)
|
self.emit_vec_elt(idx, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_serializer<S: serialization2::Serializer>(ser: &S, json: &Json) {
|
pub impl Json: serialization2::Serializable {
|
||||||
match *json {
|
fn serialize<S: serialization2::Serializer>(&self, s: &S) {
|
||||||
Number(f) => ser.emit_float(f),
|
match *self {
|
||||||
String(ref s) => ser.emit_str(*s),
|
Number(v) => v.serialize(s),
|
||||||
Boolean(b) => ser.emit_bool(b),
|
String(ref v) => v.serialize(s),
|
||||||
List(v) => {
|
Boolean(v) => v.serialize(s),
|
||||||
do ser.emit_vec(v.len()) || {
|
List(v) => v.serialize(s),
|
||||||
for v.eachi |i, elt| {
|
Object(ref v) => {
|
||||||
ser.emit_vec_elt(i, || to_serializer(ser, elt))
|
do s.emit_rec || {
|
||||||
}
|
let mut idx = 0;
|
||||||
}
|
for v.each |key, value| {
|
||||||
}
|
do s.emit_field(*key, idx) {
|
||||||
Object(ref o) => {
|
value.serialize(s);
|
||||||
do ser.emit_rec || {
|
}
|
||||||
let mut idx = 0;
|
idx += 1;
|
||||||
for o.each |key, value| {
|
|
||||||
do ser.emit_rec_field(*key, idx) {
|
|
||||||
to_serializer(ser, value);
|
|
||||||
}
|
}
|
||||||
idx += 1;
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
Null => s.emit_nil(),
|
||||||
}
|
}
|
||||||
Null => ser.emit_nil(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes a json value into a io::writer
|
/// Serializes a json value into a io::writer
|
||||||
pub fn to_writer(wr: io::Writer, json: &Json) {
|
pub fn to_writer(wr: io::Writer, json: &Json) {
|
||||||
to_serializer(&Serializer(wr), json)
|
json.serialize(&Serializer(wr))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes a json value into a string
|
/// Serializes a json value into a string
|
||||||
|
@ -284,7 +308,7 @@ pub fn to_str(json: &Json) -> ~str {
|
||||||
|
|
||||||
/// Serializes a json value into a io::writer
|
/// Serializes a json value into a io::writer
|
||||||
pub fn to_pretty_writer(wr: io::Writer, json: &Json) {
|
pub fn to_pretty_writer(wr: io::Writer, json: &Json) {
|
||||||
to_serializer(&PrettySerializer(wr), json)
|
json.serialize(&PrettySerializer(wr))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes a json value into a string
|
/// Serializes a json value into a string
|
||||||
|
@ -736,14 +760,35 @@ pub impl Deserializer: serialization2::Deserializer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_str(&self) -> ~str {
|
fn read_char(&self) -> char {
|
||||||
debug!("read_str");
|
let v = str::chars(self.read_owned_str());
|
||||||
|
if v.len() != 1 { fail ~"string must have one character" }
|
||||||
|
v[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_owned_str(&self) -> ~str {
|
||||||
|
debug!("read_owned_str");
|
||||||
match *self.pop() {
|
match *self.pop() {
|
||||||
String(ref s) => copy *s,
|
String(ref s) => copy *s,
|
||||||
_ => fail ~"not a string"
|
_ => fail ~"not a string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_managed_str(&self) -> @str {
|
||||||
|
// FIXME(#3604): There's no way to convert from a ~str to a @str.
|
||||||
|
fail ~"read_managed_str()";
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_owned<T>(&self, f: fn() -> T) -> T {
|
||||||
|
debug!("read_owned()");
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_managed<T>(&self, f: fn() -> T) -> T {
|
||||||
|
debug!("read_managed()");
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
|
fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
|
||||||
debug!("read_enum(%s)", name);
|
debug!("read_enum(%s)", name);
|
||||||
if name != ~"option" { fail ~"only supports the option enum" }
|
if name != ~"option" { fail ~"only supports the option enum" }
|
||||||
|
@ -765,8 +810,19 @@ pub impl Deserializer: serialization2::Deserializer {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_vec<T>(&self, f: fn(uint) -> T) -> T {
|
fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
|
||||||
debug!("read_vec()");
|
debug!("read_owned_vec()");
|
||||||
|
let len = match *self.peek() {
|
||||||
|
List(list) => list.len(),
|
||||||
|
_ => fail ~"not a list",
|
||||||
|
};
|
||||||
|
let res = f(len);
|
||||||
|
self.pop();
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
|
||||||
|
debug!("read_owned_vec()");
|
||||||
let len = match *self.peek() {
|
let len = match *self.peek() {
|
||||||
List(ref list) => list.len(),
|
List(ref list) => list.len(),
|
||||||
_ => fail ~"not a list",
|
_ => fail ~"not a list",
|
||||||
|
@ -790,16 +846,6 @@ pub impl Deserializer: serialization2::Deserializer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_box<T>(&self, f: fn() -> T) -> T {
|
|
||||||
debug!("read_box()");
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_uniq<T>(&self, f: fn() -> T) -> T {
|
|
||||||
debug!("read_uniq()");
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_rec<T>(&self, f: fn() -> T) -> T {
|
fn read_rec<T>(&self, f: fn() -> T) -> T {
|
||||||
debug!("read_rec()");
|
debug!("read_rec()");
|
||||||
let value = f();
|
let value = f();
|
||||||
|
@ -807,17 +853,23 @@ pub impl Deserializer: serialization2::Deserializer {
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_rec_field<T>(&self, f_name: &str, f_idx: uint,
|
fn read_struct<T>(&self, _name: &str, f: fn() -> T) -> T {
|
||||||
f: fn() -> T) -> T {
|
debug!("read_struct()");
|
||||||
debug!("read_rec_field(%s, idx=%u)", f_name, f_idx);
|
let value = f();
|
||||||
|
self.pop();
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
|
||||||
|
debug!("read_rec_field(%s, idx=%u)", name, idx);
|
||||||
let top = self.peek();
|
let top = self.peek();
|
||||||
match *top {
|
match *top {
|
||||||
Object(ref obj) => {
|
Object(ref obj) => {
|
||||||
// FIXME(#3148) This hint should not be necessary.
|
// FIXME(#3148) This hint should not be necessary.
|
||||||
let obj: &self/~Object = obj;
|
let obj: &self/~Object = obj;
|
||||||
|
|
||||||
match obj.find_ref(&(f_name.to_unique())) {
|
match obj.find_ref(&name.to_unique()) {
|
||||||
None => fail fmt!("no such field: %s", f_name),
|
None => fail fmt!("no such field: %s", name),
|
||||||
Some(json) => {
|
Some(json) => {
|
||||||
self.stack.push(json);
|
self.stack.push(json);
|
||||||
f()
|
f()
|
||||||
|
@ -834,8 +886,8 @@ pub impl Deserializer: serialization2::Deserializer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T {
|
fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
|
||||||
debug!("read_tup(sz=%u)", sz);
|
debug!("read_tup(len=%u)", len);
|
||||||
let value = f();
|
let value = f();
|
||||||
self.pop();
|
self.pop();
|
||||||
value
|
value
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer {
|
||||||
Serializer { wr: wr }
|
Serializer { wr: wr }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serializer: serialization2::Serializer {
|
pub impl Serializer: serialization2::Serializer {
|
||||||
fn emit_nil(&self) {
|
fn emit_nil(&self) {
|
||||||
self.wr.write_str(~"()")
|
self.wr.write_str(~"()")
|
||||||
}
|
}
|
||||||
|
@ -73,10 +73,37 @@ impl Serializer: serialization2::Serializer {
|
||||||
self.wr.write_str(fmt!("%?_f32", v));
|
self.wr.write_str(fmt!("%?_f32", v));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_str(&self, v: &str) {
|
fn emit_char(&self, v: char) {
|
||||||
self.wr.write_str(fmt!("%?", v));
|
self.wr.write_str(fmt!("%?", v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_borrowed_str(&self, v: &str) {
|
||||||
|
self.wr.write_str(fmt!("&%?", v));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_owned_str(&self, v: &str) {
|
||||||
|
self.wr.write_str(fmt!("~%?", v));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_managed_str(&self, v: &str) {
|
||||||
|
self.wr.write_str(fmt!("@%?", v));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_borrowed(&self, f: fn()) {
|
||||||
|
self.wr.write_str(~"&");
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_owned(&self, f: fn()) {
|
||||||
|
self.wr.write_str(~"~");
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_managed(&self, f: fn()) {
|
||||||
|
self.wr.write_str(~"@");
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_enum(&self, _name: &str, f: fn()) {
|
fn emit_enum(&self, _name: &str, f: fn()) {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
@ -94,8 +121,20 @@ impl Serializer: serialization2::Serializer {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_vec(&self, _len: uint, f: fn()) {
|
fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
|
||||||
self.wr.write_str(~"[");
|
self.wr.write_str(~"&[");
|
||||||
|
f();
|
||||||
|
self.wr.write_str(~"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_owned_vec(&self, _len: uint, f: fn()) {
|
||||||
|
self.wr.write_str(~"~[");
|
||||||
|
f();
|
||||||
|
self.wr.write_str(~"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_managed_vec(&self, _len: uint, f: fn()) {
|
||||||
|
self.wr.write_str(~"@[");
|
||||||
f();
|
f();
|
||||||
self.wr.write_str(~"]");
|
self.wr.write_str(~"]");
|
||||||
}
|
}
|
||||||
|
@ -105,30 +144,26 @@ impl Serializer: serialization2::Serializer {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_box(&self, f: fn()) {
|
|
||||||
self.wr.write_str(~"@");
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn emit_uniq(&self, f: fn()) {
|
|
||||||
self.wr.write_str(~"~");
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn emit_rec(&self, f: fn()) {
|
fn emit_rec(&self, f: fn()) {
|
||||||
self.wr.write_str(~"{");
|
self.wr.write_str(~"{");
|
||||||
f();
|
f();
|
||||||
self.wr.write_str(~"}");
|
self.wr.write_str(~"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_rec_field(&self, f_name: &str, f_idx: uint, f: fn()) {
|
fn emit_struct(&self, name: &str, f: fn()) {
|
||||||
if f_idx > 0u { self.wr.write_str(~", "); }
|
self.wr.write_str(fmt!("%s {", name));
|
||||||
self.wr.write_str(f_name);
|
f();
|
||||||
|
self.wr.write_str(~"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_field(&self, name: &str, idx: uint, f: fn()) {
|
||||||
|
if idx > 0u { self.wr.write_str(~", "); }
|
||||||
|
self.wr.write_str(name);
|
||||||
self.wr.write_str(~": ");
|
self.wr.write_str(~": ");
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_tup(&self, _sz: uint, f: fn()) {
|
fn emit_tup(&self, _len: uint, f: fn()) {
|
||||||
self.wr.write_str(~"(");
|
self.wr.write_str(~"(");
|
||||||
f();
|
f();
|
||||||
self.wr.write_str(~")");
|
self.wr.write_str(~")");
|
||||||
|
|
|
@ -24,19 +24,30 @@ pub trait Serializer {
|
||||||
fn emit_float(&self, v: float);
|
fn emit_float(&self, v: float);
|
||||||
fn emit_f64(&self, v: f64);
|
fn emit_f64(&self, v: f64);
|
||||||
fn emit_f32(&self, v: f32);
|
fn emit_f32(&self, v: f32);
|
||||||
fn emit_str(&self, v: &str);
|
fn emit_char(&self, v: char);
|
||||||
|
fn emit_borrowed_str(&self, v: &str);
|
||||||
|
fn emit_owned_str(&self, v: &str);
|
||||||
|
fn emit_managed_str(&self, v: &str);
|
||||||
|
|
||||||
// Compound types:
|
// Compound types:
|
||||||
|
fn emit_borrowed(&self, f: fn());
|
||||||
|
fn emit_owned(&self, f: fn());
|
||||||
|
fn emit_managed(&self, f: fn());
|
||||||
|
|
||||||
fn emit_enum(&self, name: &str, f: fn());
|
fn emit_enum(&self, name: &str, f: fn());
|
||||||
fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn());
|
fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn());
|
||||||
fn emit_enum_variant_arg(&self, idx: uint, f: fn());
|
fn emit_enum_variant_arg(&self, idx: uint, f: fn());
|
||||||
fn emit_vec(&self, len: uint, f: fn());
|
|
||||||
|
fn emit_borrowed_vec(&self, len: uint, f: fn());
|
||||||
|
fn emit_owned_vec(&self, len: uint, f: fn());
|
||||||
|
fn emit_managed_vec(&self, len: uint, f: fn());
|
||||||
fn emit_vec_elt(&self, idx: uint, f: fn());
|
fn emit_vec_elt(&self, idx: uint, f: fn());
|
||||||
fn emit_box(&self, f: fn());
|
|
||||||
fn emit_uniq(&self, f: fn());
|
|
||||||
fn emit_rec(&self, f: fn());
|
fn emit_rec(&self, f: fn());
|
||||||
fn emit_rec_field(&self, f_name: &str, f_idx: uint, f: fn());
|
fn emit_struct(&self, name: &str, f: fn());
|
||||||
fn emit_tup(&self, sz: uint, f: fn());
|
fn emit_field(&self, f_name: &str, f_idx: uint, f: fn());
|
||||||
|
|
||||||
|
fn emit_tup(&self, len: uint, f: fn());
|
||||||
fn emit_tup_elt(&self, idx: uint, f: fn());
|
fn emit_tup_elt(&self, idx: uint, f: fn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,29 +68,43 @@ pub trait Deserializer {
|
||||||
fn read_f64(&self) -> f64;
|
fn read_f64(&self) -> f64;
|
||||||
fn read_f32(&self) -> f32;
|
fn read_f32(&self) -> f32;
|
||||||
fn read_float(&self) -> float;
|
fn read_float(&self) -> float;
|
||||||
fn read_str(&self) -> ~str;
|
fn read_char(&self) -> char;
|
||||||
|
fn read_owned_str(&self) -> ~str;
|
||||||
|
fn read_managed_str(&self) -> @str;
|
||||||
|
|
||||||
// Compound types:
|
// Compound types:
|
||||||
fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T;
|
fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T;
|
||||||
fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T;
|
fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T;
|
||||||
fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T;
|
fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T;
|
||||||
fn read_vec<T>(&self, f: fn(uint) -> T) -> T;
|
|
||||||
|
fn read_owned<T>(&self, f: fn() -> T) -> T;
|
||||||
|
fn read_managed<T>(&self, f: fn() -> T) -> T;
|
||||||
|
|
||||||
|
fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T;
|
||||||
|
fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T;
|
||||||
fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
|
fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
|
||||||
fn read_box<T>(&self, f: fn() -> T) -> T;
|
|
||||||
fn read_uniq<T>(&self, f: fn() -> T) -> T;
|
|
||||||
fn read_rec<T>(&self, f: fn() -> T) -> T;
|
fn read_rec<T>(&self, f: fn() -> T) -> T;
|
||||||
fn read_rec_field<T>(&self, f_name: &str, f_idx: uint, f: fn() -> T) -> T;
|
fn read_struct<T>(&self, name: &str, 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;
|
fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T;
|
||||||
fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
|
fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Serializable {
|
pub trait Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S);
|
fn serialize<S: Serializer>(&self, s: &S);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> self;
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl uint: Serializable {
|
pub impl uint: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl uint: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> uint {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> uint {
|
||||||
d.read_uint()
|
d.read_uint()
|
||||||
}
|
}
|
||||||
|
@ -87,6 +112,9 @@ pub impl uint: Serializable {
|
||||||
|
|
||||||
pub impl u8: Serializable {
|
pub impl u8: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl u8: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 {
|
||||||
d.read_u8()
|
d.read_u8()
|
||||||
}
|
}
|
||||||
|
@ -94,6 +122,9 @@ pub impl u8: Serializable {
|
||||||
|
|
||||||
pub impl u16: Serializable {
|
pub impl u16: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl u16: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 {
|
||||||
d.read_u16()
|
d.read_u16()
|
||||||
}
|
}
|
||||||
|
@ -101,6 +132,9 @@ pub impl u16: Serializable {
|
||||||
|
|
||||||
pub impl u32: Serializable {
|
pub impl u32: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl u32: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 {
|
||||||
d.read_u32()
|
d.read_u32()
|
||||||
}
|
}
|
||||||
|
@ -108,6 +142,9 @@ pub impl u32: Serializable {
|
||||||
|
|
||||||
pub impl u64: Serializable {
|
pub impl u64: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl u64: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 {
|
||||||
d.read_u64()
|
d.read_u64()
|
||||||
}
|
}
|
||||||
|
@ -115,6 +152,9 @@ pub impl u64: Serializable {
|
||||||
|
|
||||||
pub impl int: Serializable {
|
pub impl int: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl int: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> int {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> int {
|
||||||
d.read_int()
|
d.read_int()
|
||||||
}
|
}
|
||||||
|
@ -122,6 +162,9 @@ pub impl int: Serializable {
|
||||||
|
|
||||||
pub impl i8: Serializable {
|
pub impl i8: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl i8: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 {
|
||||||
d.read_i8()
|
d.read_i8()
|
||||||
}
|
}
|
||||||
|
@ -129,6 +172,9 @@ pub impl i8: Serializable {
|
||||||
|
|
||||||
pub impl i16: Serializable {
|
pub impl i16: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl i16: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 {
|
||||||
d.read_i16()
|
d.read_i16()
|
||||||
}
|
}
|
||||||
|
@ -136,6 +182,9 @@ pub impl i16: Serializable {
|
||||||
|
|
||||||
pub impl i32: Serializable {
|
pub impl i32: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl i32: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 {
|
||||||
d.read_i32()
|
d.read_i32()
|
||||||
}
|
}
|
||||||
|
@ -143,20 +192,43 @@ pub impl i32: Serializable {
|
||||||
|
|
||||||
pub impl i64: Serializable {
|
pub impl i64: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl i64: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 {
|
||||||
d.read_i64()
|
d.read_i64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub impl &str: Serializable {
|
||||||
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
pub impl ~str: Serializable {
|
pub impl ~str: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_str(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl ~str: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str {
|
||||||
d.read_str()
|
d.read_owned_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl @str: Serializable {
|
||||||
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl @str: Deserializable {
|
||||||
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> @str {
|
||||||
|
d.read_managed_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl float: Serializable {
|
pub impl float: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl float: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> float {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> float {
|
||||||
d.read_float()
|
d.read_float()
|
||||||
}
|
}
|
||||||
|
@ -164,12 +236,18 @@ pub impl float: Serializable {
|
||||||
|
|
||||||
pub impl f32: Serializable {
|
pub impl f32: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl f32: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 {
|
||||||
d.read_f32() }
|
d.read_f32() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl f64: Serializable {
|
pub impl f64: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl f64: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 {
|
||||||
d.read_f64()
|
d.read_f64()
|
||||||
}
|
}
|
||||||
|
@ -177,6 +255,9 @@ pub impl f64: Serializable {
|
||||||
|
|
||||||
pub impl bool: Serializable {
|
pub impl bool: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl bool: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> bool {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> bool {
|
||||||
d.read_bool()
|
d.read_bool()
|
||||||
}
|
}
|
||||||
|
@ -184,42 +265,67 @@ pub impl bool: Serializable {
|
||||||
|
|
||||||
pub impl (): Serializable {
|
pub impl (): Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() }
|
fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl (): Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> () {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> () {
|
||||||
d.read_nil()
|
d.read_nil()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl<T: Serializable> @T: Serializable {
|
pub impl<T: Serializable> &T: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) {
|
fn serialize<S: Serializer>(&self, s: &S) {
|
||||||
s.emit_box(|| (*self).serialize(s))
|
s.emit_borrowed(|| (**self).serialize(s))
|
||||||
}
|
|
||||||
|
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
|
|
||||||
d.read_box(|| @deserialize(d))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl<T: Serializable> ~T: Serializable {
|
pub impl<T: Serializable> ~T: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) {
|
fn serialize<S: Serializer>(&self, s: &S) {
|
||||||
s.emit_uniq(|| (*self).serialize(s))
|
s.emit_owned(|| (**self).serialize(s))
|
||||||
}
|
|
||||||
|
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T {
|
|
||||||
d.read_uniq(|| ~deserialize(d))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl<T: Serializable> ~[T]: Serializable {
|
pub impl<T: Deserializable> ~T: Deserializable {
|
||||||
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T {
|
||||||
|
d.read_owned(|| ~deserialize(d))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<T: Serializable> @T: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) {
|
fn serialize<S: Serializer>(&self, s: &S) {
|
||||||
do s.emit_vec(self.len()) {
|
s.emit_managed(|| (**self).serialize(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<T: Deserializable> @T: Deserializable {
|
||||||
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
|
||||||
|
d.read_managed(|| @deserialize(d))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<T: Serializable> &[T]: Serializable {
|
||||||
|
fn serialize<S: Serializer>(&self, s: &S) {
|
||||||
|
do s.emit_borrowed_vec(self.len()) {
|
||||||
for self.eachi |i, e| {
|
for self.eachi |i, e| {
|
||||||
s.emit_vec_elt(i, || e.serialize(s))
|
s.emit_vec_elt(i, || e.serialize(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<T: Serializable> ~[T]: Serializable {
|
||||||
|
fn serialize<S: Serializer>(&self, s: &S) {
|
||||||
|
do s.emit_owned_vec(self.len()) {
|
||||||
|
for self.eachi |i, e| {
|
||||||
|
s.emit_vec_elt(i, || e.serialize(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<T: Deserializable> ~[T]: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] {
|
||||||
do d.read_vec |len| {
|
do d.read_owned_vec |len| {
|
||||||
do vec::from_fn(len) |i| {
|
do vec::from_fn(len) |i| {
|
||||||
d.read_vec_elt(i, || deserialize(d))
|
d.read_vec_elt(i, || deserialize(d))
|
||||||
}
|
}
|
||||||
|
@ -227,6 +333,26 @@ pub impl<T: Serializable> ~[T]: Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub impl<T: Serializable> @[T]: Serializable {
|
||||||
|
fn serialize<S: Serializer>(&self, s: &S) {
|
||||||
|
do s.emit_managed_vec(self.len()) {
|
||||||
|
for self.eachi |i, e| {
|
||||||
|
s.emit_vec_elt(i, || e.serialize(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<T: Deserializable> @[T]: Deserializable {
|
||||||
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] {
|
||||||
|
do d.read_managed_vec |len| {
|
||||||
|
do at_vec::from_fn(len) |i| {
|
||||||
|
d.read_vec_elt(i, || deserialize(d))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub impl<T: Serializable> Option<T>: Serializable {
|
pub impl<T: Serializable> Option<T>: Serializable {
|
||||||
fn serialize<S: Serializer>(&self, s: &S) {
|
fn serialize<S: Serializer>(&self, s: &S) {
|
||||||
do s.emit_enum(~"option") {
|
do s.emit_enum(~"option") {
|
||||||
|
@ -240,7 +366,9 @@ pub impl<T: Serializable> Option<T>: Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<T: Deserializable> Option<T>: Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> {
|
||||||
do d.read_enum(~"option") {
|
do d.read_enum(~"option") {
|
||||||
do d.read_enum_variant |i| {
|
do d.read_enum_variant |i| {
|
||||||
|
@ -268,7 +396,12 @@ pub impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<
|
||||||
|
T0: Deserializable,
|
||||||
|
T1: Deserializable
|
||||||
|
> (T0, T1): Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) {
|
||||||
do d.read_tup(2) {
|
do d.read_tup(2) {
|
||||||
(
|
(
|
||||||
|
@ -295,7 +428,13 @@ pub impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<
|
||||||
|
T0: Deserializable,
|
||||||
|
T1: Deserializable,
|
||||||
|
T2: Deserializable
|
||||||
|
> (T0, T1, T2): Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) {
|
||||||
do d.read_tup(3) {
|
do d.read_tup(3) {
|
||||||
(
|
(
|
||||||
|
@ -325,7 +464,14 @@ pub impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<
|
||||||
|
T0: Deserializable,
|
||||||
|
T1: Deserializable,
|
||||||
|
T2: Deserializable,
|
||||||
|
T3: Deserializable
|
||||||
|
> (T0, T1, T2, T3): Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) {
|
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) {
|
||||||
do d.read_tup(4) {
|
do d.read_tup(4) {
|
||||||
(
|
(
|
||||||
|
@ -358,7 +504,15 @@ pub impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl<
|
||||||
|
T0: Deserializable,
|
||||||
|
T1: Deserializable,
|
||||||
|
T2: Deserializable,
|
||||||
|
T3: Deserializable,
|
||||||
|
T4: Deserializable
|
||||||
|
> (T0, T1, T2, T3, T4): Deserializable {
|
||||||
static fn deserialize<D: Deserializer>(&self, d: &D)
|
static fn deserialize<D: Deserializer>(&self, d: &D)
|
||||||
-> (T0, T1, T2, T3, T4) {
|
-> (T0, T1, T2, T3, T4) {
|
||||||
do d.read_tup(5) {
|
do d.read_tup(5) {
|
||||||
|
@ -379,12 +533,12 @@ pub impl<
|
||||||
// In some cases, these should eventually be coded as traits.
|
// In some cases, these should eventually be coded as traits.
|
||||||
|
|
||||||
pub trait SerializerHelpers {
|
pub trait SerializerHelpers {
|
||||||
fn emit_from_vec<T>(&self, v: ~[T], f: fn(v: &T));
|
fn emit_from_vec<T>(&self, v: &[T], f: fn(&T));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl<S: Serializer> S: SerializerHelpers {
|
pub impl<S: Serializer> S: SerializerHelpers {
|
||||||
fn emit_from_vec<T>(&self, v: ~[T], f: fn(v: &T)) {
|
fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) {
|
||||||
do self.emit_vec(v.len()) {
|
do self.emit_owned_vec(v.len()) {
|
||||||
for v.eachi |i, e| {
|
for v.eachi |i, e| {
|
||||||
do self.emit_vec_elt(i) {
|
do self.emit_vec_elt(i) {
|
||||||
f(e)
|
f(e)
|
||||||
|
@ -400,7 +554,7 @@ pub trait DeserializerHelpers {
|
||||||
|
|
||||||
pub impl<D: Deserializer> D: DeserializerHelpers {
|
pub impl<D: Deserializer> D: DeserializerHelpers {
|
||||||
fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
|
fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
|
||||||
do self.read_vec |len| {
|
do self.read_owned_vec |len| {
|
||||||
do vec::from_fn(len) |i| {
|
do vec::from_fn(len) |i| {
|
||||||
self.read_vec_elt(i, || f())
|
self.read_vec_elt(i, || f())
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,14 +9,16 @@ For example, a type like:
|
||||||
|
|
||||||
type node_id = uint;
|
type node_id = uint;
|
||||||
|
|
||||||
would generate two functions like:
|
would generate two implementations like:
|
||||||
|
|
||||||
impl node_id: Serializable {
|
impl node_id: Serializable {
|
||||||
fn serialize<S: Serializer>(s: S) {
|
fn serialize<S: Serializer>(s: &S) {
|
||||||
s.emit_uint(self)
|
s.emit_uint(self)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static fn deserialize<D: Deserializer>(d: D) -> node_id {
|
impl node_id: Deserializable {
|
||||||
|
static fn deserialize<D: Deserializer>(d: &D) -> node_id {
|
||||||
d.read_uint()
|
d.read_uint()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,18 +31,20 @@ references other non-built-in types. A type definition like:
|
||||||
would yield functions like:
|
would yield functions like:
|
||||||
|
|
||||||
impl<T: Serializable> spanned<T>: Serializable {
|
impl<T: Serializable> spanned<T>: Serializable {
|
||||||
fn serialize<S: Serializer>(s: S) {
|
fn serialize<S: Serializer>(s: &S) {
|
||||||
do s.emit_rec {
|
do s.emit_rec {
|
||||||
s.emit_rec_field("node", 0, self.node.serialize(s));
|
s.emit_field("node", 0, self.node.serialize(s));
|
||||||
s.emit_rec_field("span", 1, self.span.serialize(s));
|
s.emit_field("span", 1, self.span.serialize(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static fn deserialize<D: Deserializer>(d: D) -> spanned<T> {
|
impl<T: Deserializable> spanned<T>: Deserializable {
|
||||||
|
static fn deserialize<D: Deserializer>(d: &D) -> spanned<T> {
|
||||||
do d.read_rec {
|
do d.read_rec {
|
||||||
{
|
{
|
||||||
node: d.read_rec_field(~"node", 0, || deserialize(d)),
|
node: d.read_field(~"node", 0, || deserialize(d)),
|
||||||
span: d.read_rec_field(~"span", 1, || deserialize(d)),
|
span: d.read_field(~"span", 1, || deserialize(d)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,22 +91,22 @@ fn expand(cx: ext_ctxt,
|
||||||
do vec::flat_map(in_items) |item| {
|
do vec::flat_map(in_items) |item| {
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => {
|
ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => {
|
||||||
~[
|
vec::append(
|
||||||
filter_attrs(*item),
|
~[filter_attrs(*item)],
|
||||||
mk_rec_impl(cx, item.span, item.ident, fields, tps),
|
mk_rec_impl(cx, item.span, item.ident, fields, tps)
|
||||||
]
|
)
|
||||||
},
|
},
|
||||||
ast::item_class(@{ fields, _}, tps) => {
|
ast::item_class(@{ fields, _}, tps) => {
|
||||||
~[
|
vec::append(
|
||||||
filter_attrs(*item),
|
~[filter_attrs(*item)],
|
||||||
mk_struct_impl(cx, item.span, item.ident, fields, tps),
|
mk_struct_impl(cx, item.span, item.ident, fields, tps)
|
||||||
]
|
)
|
||||||
},
|
},
|
||||||
ast::item_enum(enum_def, tps) => {
|
ast::item_enum(enum_def, tps) => {
|
||||||
~[
|
vec::append(
|
||||||
filter_attrs(*item),
|
~[filter_attrs(*item)],
|
||||||
mk_enum_impl(cx, item.span, item.ident, enum_def, tps),
|
mk_enum_impl(cx, item.span, item.ident, enum_def, tps)
|
||||||
]
|
)
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
cx.span_err(span, ~"#[auto_serialize2] can only be applied \
|
cx.span_err(span, ~"#[auto_serialize2] can only be applied \
|
||||||
|
@ -152,22 +156,11 @@ fn mk_impl(
|
||||||
cx: ext_ctxt,
|
cx: ext_ctxt,
|
||||||
span: span,
|
span: span,
|
||||||
ident: ast::ident,
|
ident: ast::ident,
|
||||||
|
path: @ast::path,
|
||||||
tps: ~[ast::ty_param],
|
tps: ~[ast::ty_param],
|
||||||
ser_body: @ast::expr,
|
f: fn(@ast::ty) -> @ast::method
|
||||||
deser_body: @ast::expr
|
|
||||||
) -> @ast::item {
|
) -> @ast::item {
|
||||||
// Make a path to the std::serialization2::Serializable trait.
|
// All the type parameters need to bound to the trait.
|
||||||
let path = cx.path(
|
|
||||||
span,
|
|
||||||
~[
|
|
||||||
cx.ident_of(~"std"),
|
|
||||||
cx.ident_of(~"serialization2"),
|
|
||||||
cx.ident_of(~"Serializable"),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
// All the type parameters need to bound to
|
|
||||||
// std::serialization::Serializable.
|
|
||||||
let trait_tps = do tps.map |tp| {
|
let trait_tps = do tps.map |tp| {
|
||||||
let t_bound = ast::bound_trait(@{
|
let t_bound = ast::bound_trait(@{
|
||||||
id: cx.next_id(),
|
id: cx.next_id(),
|
||||||
|
@ -194,23 +187,72 @@ fn mk_impl(
|
||||||
tps.map(|tp| cx.ty_path(span, ~[tp.ident], ~[]))
|
tps.map(|tp| cx.ty_path(span, ~[tp.ident], ~[]))
|
||||||
);
|
);
|
||||||
|
|
||||||
let methods = ~[
|
|
||||||
mk_ser_method(cx, span, cx.expr_blk(ser_body)),
|
|
||||||
mk_deser_method(cx, span, ty, cx.expr_blk(deser_body)),
|
|
||||||
];
|
|
||||||
|
|
||||||
@{
|
@{
|
||||||
// This is a new-style impl declaration.
|
// This is a new-style impl declaration.
|
||||||
// XXX: clownshoes
|
// XXX: clownshoes
|
||||||
ident: ast::token::special_idents::clownshoes_extensions,
|
ident: ast::token::special_idents::clownshoes_extensions,
|
||||||
attrs: ~[],
|
attrs: ~[],
|
||||||
id: cx.next_id(),
|
id: cx.next_id(),
|
||||||
node: ast::item_impl(trait_tps, opt_trait, ty, methods),
|
node: ast::item_impl(trait_tps, opt_trait, ty, ~[f(ty)]),
|
||||||
vis: ast::public,
|
vis: ast::public,
|
||||||
span: span,
|
span: span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mk_ser_impl(
|
||||||
|
cx: ext_ctxt,
|
||||||
|
span: span,
|
||||||
|
ident: ast::ident,
|
||||||
|
tps: ~[ast::ty_param],
|
||||||
|
body: @ast::expr
|
||||||
|
) -> @ast::item {
|
||||||
|
// Make a path to the std::serialization2::Serializable trait.
|
||||||
|
let path = cx.path(
|
||||||
|
span,
|
||||||
|
~[
|
||||||
|
cx.ident_of(~"std"),
|
||||||
|
cx.ident_of(~"serialization2"),
|
||||||
|
cx.ident_of(~"Serializable"),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
mk_impl(
|
||||||
|
cx,
|
||||||
|
span,
|
||||||
|
ident,
|
||||||
|
path,
|
||||||
|
tps,
|
||||||
|
|_ty| mk_ser_method(cx, span, cx.expr_blk(body))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mk_deser_impl(
|
||||||
|
cx: ext_ctxt,
|
||||||
|
span: span,
|
||||||
|
ident: ast::ident,
|
||||||
|
tps: ~[ast::ty_param],
|
||||||
|
body: @ast::expr
|
||||||
|
) -> @ast::item {
|
||||||
|
// Make a path to the std::serialization2::Deserializable trait.
|
||||||
|
let path = cx.path(
|
||||||
|
span,
|
||||||
|
~[
|
||||||
|
cx.ident_of(~"std"),
|
||||||
|
cx.ident_of(~"serialization2"),
|
||||||
|
cx.ident_of(~"Deserializable"),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
mk_impl(
|
||||||
|
cx,
|
||||||
|
span,
|
||||||
|
ident,
|
||||||
|
path,
|
||||||
|
tps,
|
||||||
|
|ty| mk_deser_method(cx, span, ty, cx.expr_blk(body))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn mk_ser_method(
|
fn mk_ser_method(
|
||||||
cx: ext_ctxt,
|
cx: ext_ctxt,
|
||||||
span: span,
|
span: span,
|
||||||
|
@ -352,7 +394,7 @@ fn mk_rec_impl(
|
||||||
ident: ast::ident,
|
ident: ast::ident,
|
||||||
fields: ~[ast::ty_field],
|
fields: ~[ast::ty_field],
|
||||||
tps: ~[ast::ty_param]
|
tps: ~[ast::ty_param]
|
||||||
) -> @ast::item {
|
) -> ~[@ast::item] {
|
||||||
// Records and structs don't have the same fields types, but they share
|
// Records and structs don't have the same fields types, but they share
|
||||||
// enough that if we extract the right subfields out we can share the
|
// enough that if we extract the right subfields out we can share the
|
||||||
// serialization generator code.
|
// serialization generator code.
|
||||||
|
@ -365,11 +407,26 @@ fn mk_rec_impl(
|
||||||
};
|
};
|
||||||
|
|
||||||
let ser_body = mk_ser_fields(cx, span, fields);
|
let ser_body = mk_ser_fields(cx, span, fields);
|
||||||
|
|
||||||
|
// ast for `__s.emit_rec($(ser_body))`
|
||||||
|
let ser_body = cx.expr_call(
|
||||||
|
span,
|
||||||
|
cx.expr_field(
|
||||||
|
span,
|
||||||
|
cx.expr_var(span, ~"__s"),
|
||||||
|
cx.ident_of(~"emit_rec")
|
||||||
|
),
|
||||||
|
~[ser_body]
|
||||||
|
);
|
||||||
|
|
||||||
let deser_body = do mk_deser_fields(cx, span, fields) |fields| {
|
let deser_body = do mk_deser_fields(cx, span, fields) |fields| {
|
||||||
cx.expr(span, ast::expr_rec(fields, None))
|
cx.expr(span, ast::expr_rec(fields, None))
|
||||||
};
|
};
|
||||||
|
|
||||||
mk_impl(cx, span, ident, tps, ser_body, deser_body)
|
~[
|
||||||
|
mk_ser_impl(cx, span, ident, tps, ser_body),
|
||||||
|
mk_deser_impl(cx, span, ident, tps, deser_body),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_struct_impl(
|
fn mk_struct_impl(
|
||||||
|
@ -378,7 +435,7 @@ fn mk_struct_impl(
|
||||||
ident: ast::ident,
|
ident: ast::ident,
|
||||||
fields: ~[@ast::struct_field],
|
fields: ~[@ast::struct_field],
|
||||||
tps: ~[ast::ty_param]
|
tps: ~[ast::ty_param]
|
||||||
) -> @ast::item {
|
) -> ~[@ast::item] {
|
||||||
// Records and structs don't have the same fields types, but they share
|
// Records and structs don't have the same fields types, but they share
|
||||||
// enough that if we extract the right subfields out we can share the
|
// enough that if we extract the right subfields out we can share the
|
||||||
// serialization generator code.
|
// serialization generator code.
|
||||||
|
@ -400,11 +457,26 @@ fn mk_struct_impl(
|
||||||
};
|
};
|
||||||
|
|
||||||
let ser_body = mk_ser_fields(cx, span, fields);
|
let ser_body = mk_ser_fields(cx, span, fields);
|
||||||
|
|
||||||
|
// ast for `__s.emit_struct($(name), $(ser_body))`
|
||||||
|
let ser_body = cx.expr_call(
|
||||||
|
span,
|
||||||
|
cx.expr_field(
|
||||||
|
span,
|
||||||
|
cx.expr_var(span, ~"__s"),
|
||||||
|
cx.ident_of(~"emit_struct")
|
||||||
|
),
|
||||||
|
~[cx.lit_str(span, @cx.str_of(ident)), ser_body]
|
||||||
|
);
|
||||||
|
|
||||||
let deser_body = do mk_deser_fields(cx, span, fields) |fields| {
|
let deser_body = do mk_deser_fields(cx, span, fields) |fields| {
|
||||||
cx.expr(span, ast::expr_struct(cx.path(span, ~[ident]), fields, None))
|
cx.expr(span, ast::expr_struct(cx.path(span, ~[ident]), fields, None))
|
||||||
};
|
};
|
||||||
|
|
||||||
mk_impl(cx, span, ident, tps, ser_body, deser_body)
|
~[
|
||||||
|
mk_ser_impl(cx, span, ident, tps, ser_body),
|
||||||
|
mk_deser_impl(cx, span, ident, tps, deser_body),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_ser_fields(
|
fn mk_ser_fields(
|
||||||
|
@ -430,14 +502,14 @@ fn mk_ser_fields(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// ast for `__s.emit_rec_field($(name), $(idx), $(expr_lambda))`
|
// ast for `__s.emit_field($(name), $(idx), $(expr_lambda))`
|
||||||
cx.stmt(
|
cx.stmt(
|
||||||
cx.expr_call(
|
cx.expr_call(
|
||||||
span,
|
span,
|
||||||
cx.expr_field(
|
cx.expr_field(
|
||||||
span,
|
span,
|
||||||
cx.expr_var(span, ~"__s"),
|
cx.expr_var(span, ~"__s"),
|
||||||
cx.ident_of(~"emit_rec_field")
|
cx.ident_of(~"emit_field")
|
||||||
),
|
),
|
||||||
~[
|
~[
|
||||||
cx.lit_str(span, @cx.str_of(field.ident)),
|
cx.lit_str(span, @cx.str_of(field.ident)),
|
||||||
|
@ -448,16 +520,8 @@ fn mk_ser_fields(
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// ast for `__s.emit_rec(|| $(stmts))`
|
// ast for `|| $(stmts)`
|
||||||
cx.expr_call(
|
cx.lambda_stmts(span, stmts)
|
||||||
span,
|
|
||||||
cx.expr_field(
|
|
||||||
span,
|
|
||||||
cx.expr_var(span, ~"__s"),
|
|
||||||
cx.ident_of(~"emit_rec")
|
|
||||||
),
|
|
||||||
~[cx.lambda_stmts(span, stmts)]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_deser_fields(
|
fn mk_deser_fields(
|
||||||
|
@ -482,13 +546,13 @@ fn mk_deser_fields(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// ast for `__d.read_rec_field($(name), $(idx), $(expr_lambda))`
|
// ast for `__d.read_field($(name), $(idx), $(expr_lambda))`
|
||||||
let expr: @ast::expr = cx.expr_call(
|
let expr: @ast::expr = cx.expr_call(
|
||||||
span,
|
span,
|
||||||
cx.expr_field(
|
cx.expr_field(
|
||||||
span,
|
span,
|
||||||
cx.expr_var(span, ~"__d"),
|
cx.expr_var(span, ~"__d"),
|
||||||
cx.ident_of(~"read_rec_field")
|
cx.ident_of(~"read_field")
|
||||||
),
|
),
|
||||||
~[
|
~[
|
||||||
cx.lit_str(span, @cx.str_of(field.ident)),
|
cx.lit_str(span, @cx.str_of(field.ident)),
|
||||||
|
@ -521,7 +585,7 @@ fn mk_enum_impl(
|
||||||
ident: ast::ident,
|
ident: ast::ident,
|
||||||
enum_def: ast::enum_def,
|
enum_def: ast::enum_def,
|
||||||
tps: ~[ast::ty_param]
|
tps: ~[ast::ty_param]
|
||||||
) -> @ast::item {
|
) -> ~[@ast::item] {
|
||||||
let ser_body = mk_enum_ser_body(
|
let ser_body = mk_enum_ser_body(
|
||||||
cx,
|
cx,
|
||||||
span,
|
span,
|
||||||
|
@ -536,7 +600,10 @@ fn mk_enum_impl(
|
||||||
enum_def.variants
|
enum_def.variants
|
||||||
);
|
);
|
||||||
|
|
||||||
mk_impl(cx, span, ident, tps, ser_body, deser_body)
|
~[
|
||||||
|
mk_ser_impl(cx, span, ident, tps, ser_body),
|
||||||
|
mk_deser_impl(cx, span, ident, tps, deser_body),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ser_variant(
|
fn ser_variant(
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
extern mod std;
|
|
||||||
|
|
||||||
// These tests used to be separate files, but I wanted to refactor all
|
|
||||||
// the common code.
|
|
||||||
|
|
||||||
use cmp::Eq;
|
|
||||||
use std::ebml2;
|
|
||||||
use io::Writer;
|
|
||||||
use std::serialization2::{Serializer, Serializable, deserialize};
|
|
||||||
use std::prettyprint2;
|
|
||||||
|
|
||||||
fn test_ser_and_deser<A:Eq Serializable>(
|
|
||||||
a1: A,
|
|
||||||
expected: ~str
|
|
||||||
) {
|
|
||||||
// check the pretty printer:
|
|
||||||
let s = do io::with_str_writer |w| {
|
|
||||||
a1.serialize(&prettyprint2::Serializer(w))
|
|
||||||
};
|
|
||||||
debug!("s == %?", s);
|
|
||||||
assert s == expected;
|
|
||||||
|
|
||||||
// check the EBML serializer:
|
|
||||||
let bytes = do io::with_bytes_writer |wr| {
|
|
||||||
let ebml_w = &ebml2::Serializer(wr);
|
|
||||||
a1.serialize(ebml_w)
|
|
||||||
};
|
|
||||||
let d = ebml2::Doc(@bytes);
|
|
||||||
let a2: A = deserialize(&ebml2::Deserializer(d));
|
|
||||||
assert a1 == a2;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[auto_serialize2]
|
|
||||||
enum Expr {
|
|
||||||
Val(uint),
|
|
||||||
Plus(@Expr, @Expr),
|
|
||||||
Minus(@Expr, @Expr)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Expr : cmp::Eq {
|
|
||||||
pure fn eq(other: &Expr) -> bool {
|
|
||||||
match self {
|
|
||||||
Val(e0a) => {
|
|
||||||
match *other {
|
|
||||||
Val(e0b) => e0a == e0b,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Plus(e0a, e1a) => {
|
|
||||||
match *other {
|
|
||||||
Plus(e0b, e1b) => e0a == e0b && e1a == e1b,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Minus(e0a, e1a) => {
|
|
||||||
match *other {
|
|
||||||
Minus(e0b, e1b) => e0a == e0b && e1a == e1b,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pure fn ne(other: &Expr) -> bool { !self.eq(other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
test_ser_and_deser(Plus(@Minus(@Val(3u), @Val(10u)),
|
|
||||||
@Plus(@Val(22u), @Val(5u))),
|
|
||||||
~"Plus(@Minus(@Val(3u), @Val(10u)), \
|
|
||||||
@Plus(@Val(22u), @Val(5u)))");
|
|
||||||
}
|
|
|
@ -6,14 +6,13 @@ extern mod std;
|
||||||
use cmp::Eq;
|
use cmp::Eq;
|
||||||
use std::ebml2;
|
use std::ebml2;
|
||||||
use io::Writer;
|
use io::Writer;
|
||||||
use std::serialization2::{Serializer, Serializable, deserialize};
|
use std::serialization2::{Serializable, Deserializable, deserialize};
|
||||||
use std::prettyprint2;
|
use std::prettyprint2;
|
||||||
|
|
||||||
fn test_ser_and_deser<A:Eq Serializable>(
|
fn test_ser_and_deser<A:Eq Serializable Deserializable>(
|
||||||
a1: A,
|
a1: A,
|
||||||
expected: ~str
|
expected: ~str
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// check the pretty printer:
|
// check the pretty printer:
|
||||||
let s = do io::with_str_writer |w| {
|
let s = do io::with_str_writer |w| {
|
||||||
a1.serialize(&prettyprint2::Serializer(w))
|
a1.serialize(&prettyprint2::Serializer(w))
|
||||||
|
@ -31,6 +30,39 @@ fn test_ser_and_deser<A:Eq Serializable>(
|
||||||
assert a1 == a2;
|
assert a1 == a2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[auto_serialize2]
|
||||||
|
enum Expr {
|
||||||
|
Val(uint),
|
||||||
|
Plus(@Expr, @Expr),
|
||||||
|
Minus(@Expr, @Expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Expr : cmp::Eq {
|
||||||
|
pure fn eq(other: &Expr) -> bool {
|
||||||
|
match self {
|
||||||
|
Val(e0a) => {
|
||||||
|
match *other {
|
||||||
|
Val(e0b) => e0a == e0b,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Plus(e0a, e1a) => {
|
||||||
|
match *other {
|
||||||
|
Plus(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Minus(e0a, e1a) => {
|
||||||
|
match *other {
|
||||||
|
Minus(e0b, e1b) => e0a == e0b && e1a == e1b,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pure fn ne(other: &Expr) -> bool { !self.eq(other) }
|
||||||
|
}
|
||||||
|
|
||||||
impl AnEnum : cmp::Eq {
|
impl AnEnum : cmp::Eq {
|
||||||
pure fn eq(other: &AnEnum) -> bool {
|
pure fn eq(other: &AnEnum) -> bool {
|
||||||
self.v == other.v
|
self.v == other.v
|
||||||
|
@ -101,15 +133,20 @@ enum Quark<T> {
|
||||||
enum CLike { A, B, C }
|
enum CLike { A, B, C }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
test_ser_and_deser(Plus(@Minus(@Val(3u), @Val(10u)),
|
||||||
|
@Plus(@Val(22u), @Val(5u))),
|
||||||
|
~"Plus(@Minus(@Val(3u), @Val(10u)), \
|
||||||
|
@Plus(@Val(22u), @Val(5u)))");
|
||||||
|
|
||||||
test_ser_and_deser({lo: 0u, hi: 5u, node: 22u},
|
test_ser_and_deser({lo: 0u, hi: 5u, node: 22u},
|
||||||
~"{lo: 0u, hi: 5u, node: 22u}");
|
~"{lo: 0u, hi: 5u, node: 22u}");
|
||||||
|
|
||||||
test_ser_and_deser(AnEnum({v: ~[1u, 2u, 3u]}),
|
test_ser_and_deser(AnEnum({v: ~[1u, 2u, 3u]}),
|
||||||
~"AnEnum({v: [1u, 2u, 3u]})");
|
~"AnEnum({v: ~[1u, 2u, 3u]})");
|
||||||
|
|
||||||
test_ser_and_deser({x: 3u, y: 5u}, ~"{x: 3u, y: 5u}");
|
test_ser_and_deser({x: 3u, y: 5u}, ~"{x: 3u, y: 5u}");
|
||||||
|
|
||||||
test_ser_and_deser(~[1u, 2u, 3u], ~"[1u, 2u, 3u]");
|
test_ser_and_deser(@[1u, 2u, 3u], ~"@[1u, 2u, 3u]");
|
||||||
|
|
||||||
test_ser_and_deser(Top(22u), ~"Top(22u)");
|
test_ser_and_deser(Top(22u), ~"Top(22u)");
|
||||||
test_ser_and_deser(Bottom(222u), ~"Bottom(222u)");
|
test_ser_and_deser(Bottom(222u), ~"Bottom(222u)");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue