From f66d8bcf33530c858a502bfa170f2383a8cbc204 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 29 Jan 2017 16:53:20 -0800 Subject: Rewrite crate with serde support from ground up This commit completely rewrites this crate from the ground up, supporting serde at the lowest levels as I believe serde support was intended to do. This is a major change from the previous versions of this crate, with a summary of changes being: * Serialization directly to TOML is now supported without going through a `Value` first. * Deserialization directly from TOML is now supported without going through a `Value`. Note that due to the TOML format some values still are buffered in intermediate memory, but overall this should be at a minimum now. * The API of `Value` was overhauled to match the API of `serde_json::Value`. The changes here were to: * Add `is_*` accessors * Add `get` and `get_mut` for one-field lookups. * Implement panicking lookups through `Index` The old `index` methods are now gone in favor of `get` and `Index` implementations. * A `Datetime` type has been added to represent a TOML datetime in a first-class fashion. Currently this type provides no accessors other than a `Display` implementation, but the idea is that this will grow support over time for decomposing the date. * Support for the `rustc-serialize` crate has been dropped, that'll stay on the 0.2 and 0.1 release trains. * This crate no longer supports the detection of unused fields, for that though you can use the `serde_ignored` crate on crates.io --- tests/valid.rs | 68 +++++++++++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) (limited to 'tests/valid.rs') diff --git a/tests/valid.rs b/tests/valid.rs index 09589c9..4229f1c 100644 --- a/tests/valid.rs +++ b/tests/valid.rs @@ -1,65 +1,61 @@ -extern crate rustc_serialize; extern crate toml; +extern crate serde_json; -use std::collections::BTreeMap; -use rustc_serialize::json::Json; +use toml::Value as Toml; +use serde_json::Value as Json; -use toml::{Parser, Value}; -use toml::Value::{Table, Integer, Float, Boolean, Datetime, Array}; - -fn to_json(toml: Value) -> Json { +fn to_json(toml: toml::Value) -> Json { fn doit(s: &str, json: Json) -> Json { - let mut map = BTreeMap::new(); - map.insert(format!("{}", "type"), Json::String(format!("{}", s))); - map.insert(format!("{}", "value"), json); + let mut map = serde_json::Map::new(); + map.insert("type".to_string(), Json::String(s.to_string())); + map.insert("value".to_string(), json); Json::Object(map) } + match toml { - Value::String(s) => doit("string", Json::String(s)), - Integer(i) => doit("integer", Json::String(format!("{}", i))), - Float(f) => doit("float", Json::String({ + Toml::String(s) => doit("string", Json::String(s)), + Toml::Integer(i) => doit("integer", Json::String(i.to_string())), + Toml::Float(f) => doit("float", Json::String({ let s = format!("{:.15}", f); let s = format!("{}", s.trim_right_matches('0')); if s.ends_with(".") {format!("{}0", s)} else {s} })), - Boolean(b) => doit("bool", Json::String(format!("{}", b))), - Datetime(s) => doit("datetime", Json::String(s)), - Array(arr) => { + Toml::Boolean(b) => doit("bool", Json::String(format!("{}", b))), + Toml::Datetime(s) => doit("datetime", Json::String(s.to_string())), + Toml::Array(arr) => { let is_table = match arr.first() { - Some(&Table(..)) => true, + Some(&Toml::Table(..)) => true, _ => false, }; let json = Json::Array(arr.into_iter().map(to_json).collect()); if is_table {json} else {doit("array", json)} } - Table(table) => Json::Object(table.into_iter().map(|(k, v)| { - (k, to_json(v)) - }).collect()), + Toml::Table(table) => { + let mut map = serde_json::Map::new(); + for (k, v) in table { + map.insert(k, to_json(v)); + } + Json::Object(map) + } } } fn run(toml: &str, json: &str) { - let mut p = Parser::new(toml); - let table = p.parse(); - assert!(p.errors.len() == 0, "had_errors: {:?}", - p.errors.iter().map(|e| { - (e.desc.clone(), &toml[e.lo - 5..e.hi + 5]) - }).collect::>()); - assert!(table.is_some()); - let toml = Table(table.unwrap()); - let toml_string = format!("{}", toml); + println!("parsing:\n{}", toml); + let toml: Toml = toml.parse().unwrap(); + let json: Json = json.parse().unwrap(); - let json = Json::from_str(json).unwrap(); + // Assert toml == json let toml_json = to_json(toml.clone()); assert!(json == toml_json, "expected\n{}\ngot\n{}\n", - json.pretty(), - toml_json.pretty()); + serde_json::to_string_pretty(&json).unwrap(), + serde_json::to_string_pretty(&toml_json).unwrap()); - let table2 = Parser::new(&toml_string).parse().unwrap(); - // floats are a little lossy - if table2.values().any(|v| v.as_float().is_some()) { return } - assert_eq!(toml, Table(table2)); + // Assert round trip + println!("round trip parse: {}", toml); + let toml2 = toml.to_string().parse().unwrap(); + assert_eq!(toml, toml2); } macro_rules! test( ($name:ident, $toml:expr, $json:expr) => ( -- cgit v1.2.3