about summary refs log tree commit diff
path: root/src/libsyntax/ext/auto_encode.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-03-27 21:51:53 -0700
committerbors <bors@rust-lang.org>2013-03-27 21:51:53 -0700
commit84ddff3909b5920228642649b7f5cc011c0b900a (patch)
tree25cfe9b7ddd20bc08ea56de4fe87dbabf9a885f0 /src/libsyntax/ext/auto_encode.rs
parent4954d3e50177c46d260a5340ff91bfada8590ef0 (diff)
parentc317d3f6fa9475e65b6276743c09444441059ca7 (diff)
downloadrust-84ddff3909b5920228642649b7f5cc011c0b900a.tar.gz
rust-84ddff3909b5920228642649b7f5cc011c0b900a.zip
auto merge of #5578 : erickt/rust/incoming, r=jbclements,erickt
Hey folks,

This patch series does some work on the json decoder, specifically with auto decoding of enums. Previously, we would take this code:

```
enum A {
    B,
    C(~str, uint)
}
```

and would encode a value of this enum to either `["B", []]` or `["C", ["D", 123]]`. I've changed this to `"B"` or `["C", "D", 123]`. This matches the style of the O'Caml json library [json-wheel](http://mjambon.com/json-wheel.html). I've added tests to make sure all this work.

In order to make this change, I added passing a `&[&str]` vec to `Decode::emit_enum_variant` so the json decoder can convert the name of a variant into it's position. I also changed the impl of `Encodable` for `Option<T>` to have the right upper casing.

I also did some work on the parser, which allows for `fn foo<T: ::cmp::Eq>() { ... }` statements (#5572), fixed the pretty printer properly expanding `debug!("...")` expressions, and removed `ast::expr_vstore_fixed`, which doesn't appear to be used anymore.
Diffstat (limited to 'src/libsyntax/ext/auto_encode.rs')
-rw-r--r--src/libsyntax/ext/auto_encode.rs96
1 files changed, 84 insertions, 12 deletions
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index e81e460e832..2a112f106a8 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -1059,6 +1059,18 @@ fn mk_enum_deser_body(
     name: ast::ident,
     variants: ~[ast::variant]
 ) -> @ast::expr {
+    let expr_arm_names = build::mk_base_vec_e(
+        ext_cx,
+        span,
+         do variants.map |variant| {
+            build::mk_base_str(
+                ext_cx,
+                span,
+                ext_cx.str_of(variant.node.name)
+            )
+        }
+    );
+
     let mut arms = do variants.mapi |v_idx, variant| {
         let body = match variant.node.kind {
             ast::tuple_variant_kind(ref args) => {
@@ -1152,13 +1164,13 @@ fn mk_enum_deser_body(
         )
     );
 
-    // ast for `__d.read_enum_variant($(expr_lambda))`
+    // ast for `__d.read_enum_variant($expr_arm_names, $(expr_lambda))`
     let expr_lambda = ext_cx.lambda_expr(
         ext_cx.expr_method_call(
             span,
             ext_cx.expr_var(span, ~"__d"),
             ext_cx.ident_of(~"read_enum_variant"),
-            ~[expr_lambda]
+            ~[expr_arm_names, expr_lambda]
         )
     );
 
@@ -1174,9 +1186,9 @@ fn mk_enum_deser_body(
     )
 }
 
-
 #[cfg(test)]
 mod test {
+    use core::option::{None, Some};
     use std::serialize::Encodable;
     use std::serialize::Encoder;
 
@@ -1190,6 +1202,9 @@ mod test {
         CallToEmitNil,
         CallToEmitStruct(~str,uint),
         CallToEmitField(~str,uint),
+        CallToEmitOption,
+        CallToEmitOptionNone,
+        CallToEmitOptionSome,
         // all of the ones I was too lazy to handle:
         CallToOther
     }
@@ -1281,6 +1296,18 @@ mod test {
         fn emit_tup_elt(&self, +_idx: uint, f: &fn()) {
             self.add_unknown_to_log(); f();
         }
+
+        fn emit_option(&self, f: &fn()) {
+            self.add_to_log(CallToEmitOption);
+            f();
+        }
+        fn emit_option_none(&self) {
+            self.add_to_log(CallToEmitOptionNone);
+        }
+        fn emit_option_some(&self, f: &fn()) {
+            self.add_to_log(CallToEmitOptionSome);
+            f();
+        }
     }
 
 
@@ -1296,13 +1323,58 @@ mod test {
         Magazine(~str)
     }
 
-    #[test] fn encode_enum_test () {
-        assert_eq!(to_call_log(Book(34,44)),
-                     ~[CallToEmitEnum (~"Written"),
-                       CallToEmitEnumVariant (~"Book",0,2),
-                       CallToEmitEnumVariantArg (0),
-                       CallToEmitUint (34),
-                       CallToEmitEnumVariantArg (1),
-                       CallToEmitUint (44)]);
-        }
+    #[test]
+    fn test_encode_enum() {
+        assert_eq!(
+            to_call_log(Book(34,44)),
+            ~[
+                CallToEmitEnum(~"Written"),
+                CallToEmitEnumVariant(~"Book",0,2),
+                CallToEmitEnumVariantArg(0),
+                CallToEmitUint(34),
+                CallToEmitEnumVariantArg(1),
+                CallToEmitUint(44),
+            ]
+        );
+    }
+
+    pub struct BPos(uint);
+
+    #[auto_encode]
+    pub struct HasPos { pos : BPos }
+
+    #[test]
+    fn test_encode_newtype() {
+        assert_eq!(
+            to_call_log(HasPos { pos:BPos(48) }),
+            ~[
+                CallToEmitStruct(~"HasPos",1),
+                CallToEmitField(~"pos",0),
+                CallToEmitUint(48),
+            ]
+        );
+    }
+
+    #[test]
+    fn test_encode_option() {
+        let mut v = None;
+
+        assert_eq!(
+            to_call_log(v),
+            ~[
+                CallToEmitOption,
+                CallToEmitOptionNone,
+            ]
+        );
+
+        v = Some(54u);
+        assert_eq!(
+            to_call_log(v),
+            ~[
+                CallToEmitOption,
+                CallToEmitOptionSome,
+                CallToEmitUint(54)
+            ]
+        );
+    }
 }