auto merge of #9231 : cmr/rust/enum_encoding, r=catamorphism

This commit is contained in:
bors 2013-09-16 17:55:46 -07:00
commit 2f96c22a21
2 changed files with 147 additions and 38 deletions

View File

@ -135,18 +135,21 @@ impl serialize::Encoder for Encoder {
_id: uint,
cnt: uint,
f: &fn(&mut Encoder)) {
// enums are encoded as strings or vectors:
// enums are encoded as strings or objects
// Bunny => "Bunny"
// Kangaroo(34,"William") => ["Kangaroo",[34,"William"]]
// Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
if cnt == 0 {
self.wr.write_str(escape_str(name));
} 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_char(',');
self.wr.write_str("\"fields\"");
self.wr.write_str(":[");
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);
let name = match self.stack.pop() {
String(s) => s,
List(list) => {
for v in list.move_rev_iter() {
self.stack.push(v);
}
match self.stack.pop() {
String(s) => s,
value => fail!("invalid variant name: %?", value),
Object(o) => {
let n = match o.find(&~"variant").expect("invalidly encoded json") {
&String(ref s) => s.clone(),
_ => fail!("invalidly encoded json"),
};
match o.find(&~"fields").expect("invalidly encoded json") {
&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),
};
@ -1517,7 +1526,7 @@ mod tests {
let mut encoder = Encoder(wr);
animal.encode(&mut encoder);
},
~"[\"Frog\",\"Henry\",349]"
~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
);
assert_eq!(
do io::with_str_writer |wr| {
@ -1921,14 +1930,14 @@ mod tests {
assert_eq!(value, Dog);
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);
assert_eq!(value, Frog(~"Henry", 349));
}
#[test]
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 map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder);

View File

@ -398,30 +398,130 @@ mod test {
#[test] fn string_to_tts_1 () {
let (tts,_ps) = string_to_tts_and_sess(@"fn a (b : int) { b; }");
assert_eq!(to_json_str(@tts),
~"[\
[\"tt_tok\",null,[\"IDENT\",\"fn\",false]],\
[\"tt_tok\",null,[\"IDENT\",\"a\",false]],\
[\
\"tt_delim\",\
[\
[\"tt_tok\",null,\"LPAREN\"],\
[\"tt_tok\",null,[\"IDENT\",\"b\",false]],\
[\"tt_tok\",null,\"COLON\"],\
[\"tt_tok\",null,[\"IDENT\",\"int\",false]],\
[\"tt_tok\",null,\"RPAREN\"]\
]\
],\
[\
\"tt_delim\",\
[\
[\"tt_tok\",null,\"LBRACE\"],\
[\"tt_tok\",null,[\"IDENT\",\"b\",false]],\
[\"tt_tok\",null,\"SEMI\"],\
[\"tt_tok\",null,\"RBRACE\"]\
]\
~"[\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
{\
\"variant\":\"IDENT\",\
\"fields\":[\
\"fn\",\
false\
]\
]"
);
}\
]\
},\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
{\
\"variant\":\"IDENT\",\
\"fields\":[\
\"a\",\
false\
]\
}\
]\
},\
{\
\"variant\":\"tt_delim\",\
\"fields\":[\
[\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
\"LPAREN\"\
]\
},\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
{\
\"variant\":\"IDENT\",\
\"fields\":[\
\"b\",\
false\
]\
}\
]\
},\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
\"COLON\"\
]\
},\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
{\
\"variant\":\"IDENT\",\
\"fields\":[\
\"int\",\
false\
]\
}\
]\
},\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
\"RPAREN\"\
]\
}\
]\
]\
},\
{\
\"variant\":\"tt_delim\",\
\"fields\":[\
[\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
\"LBRACE\"\
]\
},\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
{\
\"variant\":\"IDENT\",\
\"fields\":[\
\"b\",\
false\
]\
}\
]\
},\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
\"SEMI\"\
]\
},\
{\
\"variant\":\"tt_tok\",\
\"fields\":[\
null,\
\"RBRACE\"\
]\
}\
]\
]\
}\
]"
);
}
#[test] fn ret_expr() {