diff --git a/Cargo.toml b/Cargo.toml index fe9cafb..dab2e24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ license = "MIT" name = "json_macros" readme = "README.markdown" repository = "https://github.com/tomjakubowski/json_macros" -version = "0.3.2" +version = "0.4.0" [features] default = ["with-rustc-serialize"] @@ -19,10 +19,10 @@ with-serde = ["serde_json"] [dependencies] rustc-serialize = { version = "^0.3", optional = true } -serde_json = { version = "^0.6", optional = true } +serde_json = { version = "^0.9", optional = true } [dev-dependencies] -serde = "^0.6" +serde = "^0.9" [[example]] name = "kitchen-sink" diff --git a/src/plugin.rs b/src/plugin.rs index a2dea53..98c2760 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -153,7 +153,7 @@ fn parse_json(cx: &ExtCtxt, parser: &mut Parser) -> P { })); } let expr = quote_expr!(cx, { - let mut _ob = ::std::collections::BTreeMap::new(); + let mut _ob = ::serde_json::Map::new(); $insertions; ::serde_json::Value::Object(_ob) }); @@ -162,7 +162,7 @@ fn parse_json(cx: &ExtCtxt, parser: &mut Parser) -> P { &Token::OpenDelim(DelimToken::Paren) => { let expr = parser.parse_expr().unwrap(); quote_expr!(cx, {{ - ::serde_json::to_value(&$expr) + ::serde_json::to_value(&$expr).unwrap() //TODO: unwrap ok here? }}) } &Token::Ident(id) if id.name == "null" => { @@ -175,7 +175,7 @@ fn parse_json(cx: &ExtCtxt, parser: &mut Parser) -> P { // TODO: investigate can_begin_expr (maybe eliminate need for parens)? let expr = parser.parse_pat_literal_maybe_minus().ok().unwrap(); quote_expr!(cx, {{ - ::serde_json::to_value(&$expr) + ::serde_json::to_value(&$expr).unwrap() //TODO: unwrap ok here? }}) } } diff --git a/tests/tests.rs b/tests/tests.rs index 5be04fb..65e497f 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,49 +1,82 @@ #![feature(plugin)] #![plugin(json_macros)] -use std::collections::BTreeMap; - #[cfg(feature="with-serde")] extern crate serde_json; #[cfg(feature="with-rustc-serialize")] extern crate rustc_serialize; + #[cfg(feature="with-serde")] mod imports { pub use serde_json::value::Value; - use serde_json::value::Serializer; + use serde_json::value::ToJson; extern crate serde; use self::serde::ser::Serialize; - + // convenience fn to avoid re-writing tests, close to serde_json's // to_value function. // (when https://github.com/serde-rs/json/pull/52 lands this can // just re-export serde_json::value:;to_value) pub fn to_value(value: &T) -> Value where T: Serialize { - let mut ser = Serializer::new(); - value.serialize(&mut ser).ok().unwrap(); - ser.unwrap() + value.to_json().unwrap() + } + + pub fn empty_map() -> ::serde_json::Map { + ::serde_json::Map::new() + } + + pub fn to_string(json: &Value) -> String { + ::serde_json::to_string(&json).unwrap() + } + + pub fn to_string_pretty(json: &Value) -> String{ + ::serde_json::to_string_pretty(&json).unwrap() } } + #[cfg(feature="with-rustc-serialize")] mod imports { pub use rustc_serialize::json::ToJson; // convenience renaming for rough serde compatibility pub use rustc_serialize::json::Json as Value; + pub use std::collections::BTreeMap; // convenience fn to avoid re-writing tests, close to serde_json's // to_value function. pub fn to_value(value: &T) -> Value where T: ToJson { value.to_json() } + + pub fn empty_map() -> BTreeMap { + BTreeMap::new() + } + + pub fn to_string(json: &Value) -> String { + ::rustc_serialize::json::encode(&json).unwrap() + } + + pub fn to_string_pretty(json: &Value) -> String { + let mut result = String::new(); + { + use ::rustc_serialize::Encodable; + let mut encoder = ::rustc_serialize::json::Encoder::new_pretty(&mut result); + let _ = json.encode(&mut encoder); + } + result + } } use imports::*; + #[test] fn test_string_lit() { + #[cfg(feature="with-rustc-serialize")] assert_eq!(json!("foo").as_string(), Some("foo")); + #[cfg(feature="with-serde")] + assert_eq!(json!("foo").as_str(), Some("foo")); } #[test] @@ -59,12 +92,20 @@ fn test_null_lit() { assert!(json!(null).is_null()); } +#[cfg(feature="with-rustc-serialize")] #[test] fn test_bool_lit() { assert_eq!(json!(true).as_boolean(), Some(true)); assert_eq!(json!(false).as_boolean(), Some(false)); } +#[cfg(feature="with-serde")] +#[test] +fn test_bool_lit() { + assert_eq!(json!(true).as_bool(), Some(true)); + assert_eq!(json!(false).as_bool(), Some(false)); +} + #[test] fn test_array_lit() { assert_eq!(json!([]), Value::Array(vec![])); @@ -81,14 +122,14 @@ fn test_array_lit() { #[test] fn test_object_lit() { - let empty = BTreeMap::new(); + let empty = empty_map(); assert_eq!(json!({}), Value::Object(empty)); - let mut foo_bar = BTreeMap::new(); + let mut foo_bar = empty_map(); foo_bar.insert("foo".to_string(), json!("bar")); assert_eq!(json!({"foo": "bar"}), Value::Object(foo_bar)); - let mut foo_bar_baz_123 = BTreeMap::new(); + let mut foo_bar_baz_123 = empty_map(); foo_bar_baz_123.insert("foo".to_string(), json!("bar")); foo_bar_baz_123.insert("baz".to_string(), json!(123)); assert_eq!(json!({ @@ -96,8 +137,8 @@ fn test_object_lit() { "baz": 123 }), Value::Object(foo_bar_baz_123)); - let mut nested = BTreeMap::new(); - let mut bar_baz = BTreeMap::new(); + let mut nested = empty_map(); + let mut bar_baz = empty_map(); bar_baz.insert("bar".to_string(), json!("baz")); nested.insert("foo".to_string(), Value::Object(bar_baz)); nested.insert("quux".to_string(), Value::Null); @@ -113,6 +154,25 @@ fn test_expr_insertion() { let json = json!({ "message": (hello.to_string()) }); + + #[cfg(feature="with-rustc-serialize")] assert_eq!(json.find("message").and_then(|j| j.as_string()), Some(hello)); + #[cfg(feature="with-serde")] + assert_eq!(json.get("message").and_then(|j| j.as_str()), + Some(hello)); } + +#[test] +fn test_print() { + let json = json!({ + "message": "hello world!", + "nested": { + "number": 12 + } + }); + println!("JSON IS {:?}",json); + assert_eq!(to_string(&json), "{\"message\":\"hello world!\",\"nested\":{\"number\":12}}"); + assert_eq!(to_string_pretty(&json),"{\n \"message\": \"hello world!\",\n \"nested\": {\n \"number\": 12\n }\n}"); +} +