fn decode(d: &D) -> Node {
d.read_struct("Node", 1, || {
Node {
- id: d.read_field(~"x", 0, || decode(d))
+ id: d.read_field("x".to_owned(), 0, || decode(d))
}
})
}
fn decode(d: &D) -> spanned<T> {
d.read_rec(|| {
{
- node: d.read_field(~"node", 0, || decode(d)),
- span: d.read_field(~"span", 1, || decode(d)),
+ node: d.read_field("node".to_owned(), 0, || decode(d)),
+ span: d.read_field("span".to_owned(), 1, || decode(d)),
}
})
}
```
*/
-use ast::{MetaItem, Item, Expr, MutMutable};
+use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil};
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use ext::deriving::generic::*;
use parse::token;
-use std::vec::Vec;
-
pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
span: Span,
mitem: @MetaItem,
span: span,
attributes: Vec::new(),
path: Path::new_(vec!("serialize", "Encodable"), None,
- vec!(~Literal(Path::new_local("__E"))), true),
+ vec!(~Literal(Path::new_local("__S")),
+ ~Literal(Path::new_local("__E"))), true),
additional_bounds: Vec::new(),
generics: LifetimeBounds {
lifetimes: Vec::new(),
- bounds: vec!(("__E", vec!(Path::new(vec!("serialize", "Encoder"))))),
+ bounds: vec!(("__S", vec!(Path::new_(
+ vec!("serialize", "Encoder"), None,
+ vec!(~Literal(Path::new_local("__E"))), true))),
+ ("__E", vec!()))
},
methods: vec!(
MethodDef {
name: "encode",
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
- args: vec!(Ptr(~Literal(Path::new_local("__E")),
+ args: vec!(Ptr(~Literal(Path::new_local("__S")),
Borrowed(None, MutMutable))),
- ret_ty: nil_ty(),
+ ret_ty: Literal(Path::new_(vec!("std", "result", "Result"),
+ None,
+ vec!(~Tuple(Vec::new()),
+ ~Literal(Path::new_local("__E"))),
+ true)),
inline: false,
const_nonmatching: true,
combine_substructure: encodable_substructure,
Struct(ref fields) => {
let emit_struct_field = cx.ident_of("emit_struct_field");
let mut stmts = Vec::new();
+ let last = fields.len() - 1;
for (i, &FieldInfo {
name,
self_,
vec!(cx.expr_str(span, name),
cx.expr_uint(span, i),
lambda));
+
+ // last call doesn't need a try!
+ let call = if i != last {
+ cx.expr_try(span, call)
+ } else {
+ cx.expr(span, ExprRet(Some(call)))
+ };
stmts.push(cx.stmt_expr(call));
}
let encoder = cx.expr_ident(trait_span, blkarg);
let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
let mut stmts = Vec::new();
+ let last = fields.len() - 1;
for (i, &FieldInfo { self_, span, .. }) in fields.iter().enumerate() {
let enc = cx.expr_method_call(span, self_, encode, vec!(blkencoder));
let lambda = cx.lambda_expr_1(span, enc, blkarg);
emit_variant_arg,
vec!(cx.expr_uint(span, i),
lambda));
+ let call = if i != last {
+ cx.expr_try(span, call)
+ } else {
+ cx.expr(span, ExprRet(Some(call)))
+ };
stmts.push(cx.stmt_expr(call));
}
+ // enums with no fields need to return Ok()
+ if stmts.len() == 0 {
+ let ret_ok = cx.expr(trait_span,
+ ExprRet(Some(cx.expr_ok(trait_span,
+ cx.expr_lit(trait_span, LitNil)))));
+ stmts.push(cx.stmt_expr(ret_ok));
+ }
+
let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
let name = cx.expr_str(trait_span, token::get_ident(variant.node.name));
let call = cx.expr_method_call(trait_span, blkencoder,