]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax/ext/deriving/encodable.rs
Replace all ~"" with "".to_owned()
[rust.git] / src / libsyntax / ext / deriving / encodable.rs
index 0550e64bef8b1f3f76d81af2a0c99263d28fd03a..1c3edce96fb1dcd7427ab62e24761c5371f7931b 100644 (file)
@@ -36,7 +36,7 @@ impl<D:Decoder> Decodable for node_id {
     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))
             }
         })
     }
@@ -73,8 +73,8 @@ impl<
         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)),
                 }
             })
         }
@@ -82,15 +82,13 @@ fn decode(d: &D) -> spanned<T> {
 ```
 */
 
-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,
@@ -100,20 +98,28 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
         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,
@@ -135,6 +141,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
         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_,
@@ -154,6 +161,13 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                                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));
             }
 
@@ -177,6 +191,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             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);
@@ -184,9 +199,22 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                                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,