extra::json: use a different encoding for enums.
It now uses `{"type": VariantName, "fields": [...]}`, which, according to @Seldaek, since all enums will have the same "shape" rather than being a weird ad-hoc array, will optimize better in javascript JITs. It also looks prettier, and makes more sense.
This commit is contained in:
parent
507a7f093d
commit
9ea295b7df
1 changed files with 24 additions and 15 deletions
|
@ -135,18 +135,21 @@ impl serialize::Encoder for Encoder {
|
||||||
_id: uint,
|
_id: uint,
|
||||||
cnt: uint,
|
cnt: uint,
|
||||||
f: &fn(&mut Encoder)) {
|
f: &fn(&mut Encoder)) {
|
||||||
// enums are encoded as strings or vectors:
|
// enums are encoded as strings or objects
|
||||||
// Bunny => "Bunny"
|
// Bunny => "Bunny"
|
||||||
// Kangaroo(34,"William") => ["Kangaroo",[34,"William"]]
|
// Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
|
||||||
|
|
||||||
if cnt == 0 {
|
if cnt == 0 {
|
||||||
self.wr.write_str(escape_str(name));
|
self.wr.write_str(escape_str(name));
|
||||||
} else {
|
} else {
|
||||||
self.wr.write_char('[');
|
self.wr.write_char('{');
|
||||||
|
self.wr.write_str("\"variant\"");
|
||||||
|
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(',');
|
||||||
|
self.wr.write_str("\"fields\"");
|
||||||
|
self.wr.write_str(":[");
|
||||||
f(self);
|
f(self);
|
||||||
self.wr.write_char(']');
|
self.wr.write_str("]}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,14 +950,20 @@ impl serialize::Decoder for Decoder {
|
||||||
debug!("read_enum_variant(names=%?)", names);
|
debug!("read_enum_variant(names=%?)", names);
|
||||||
let name = match self.stack.pop() {
|
let name = match self.stack.pop() {
|
||||||
String(s) => s,
|
String(s) => s,
|
||||||
List(list) => {
|
Object(o) => {
|
||||||
for v in list.move_rev_iter() {
|
let n = match o.find(&~"variant").expect("invalidly encoded json") {
|
||||||
self.stack.push(v);
|
&String(ref s) => s.clone(),
|
||||||
}
|
_ => fail!("invalidly encoded json"),
|
||||||
match self.stack.pop() {
|
};
|
||||||
String(s) => s,
|
match o.find(&~"fields").expect("invalidly encoded json") {
|
||||||
value => fail!("invalid variant name: %?", value),
|
&List(ref l) => {
|
||||||
|
for field in l.rev_iter() {
|
||||||
|
self.stack.push(field.clone());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => fail!("invalidly encoded json")
|
||||||
}
|
}
|
||||||
|
n
|
||||||
}
|
}
|
||||||
ref json => fail!("invalid variant: %?", *json),
|
ref json => fail!("invalid variant: %?", *json),
|
||||||
};
|
};
|
||||||
|
@ -1517,7 +1526,7 @@ mod tests {
|
||||||
let mut encoder = Encoder(wr);
|
let mut encoder = Encoder(wr);
|
||||||
animal.encode(&mut encoder);
|
animal.encode(&mut encoder);
|
||||||
},
|
},
|
||||||
~"[\"Frog\",\"Henry\",349]"
|
~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
do io::with_str_writer |wr| {
|
do io::with_str_writer |wr| {
|
||||||
|
@ -1921,14 +1930,14 @@ mod tests {
|
||||||
assert_eq!(value, Dog);
|
assert_eq!(value, Dog);
|
||||||
|
|
||||||
let mut decoder =
|
let mut decoder =
|
||||||
Decoder(from_str("[\"Frog\",\"Henry\",349]").unwrap());
|
Decoder(from_str("{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}").unwrap());
|
||||||
let value: Animal = Decodable::decode(&mut decoder);
|
let value: Animal = Decodable::decode(&mut decoder);
|
||||||
assert_eq!(value, Frog(~"Henry", 349));
|
assert_eq!(value, Frog(~"Henry", 349));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_map() {
|
fn test_decode_map() {
|
||||||
let s = ~"{\"a\": \"Dog\", \"b\": [\"Frog\", \"Henry\", 349]}";
|
let s = ~"{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\"fields\":[\"Henry\", 349]}}";
|
||||||
let mut decoder = Decoder(from_str(s).unwrap());
|
let mut decoder = Decoder(from_str(s).unwrap());
|
||||||
let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder);
|
let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue