From 46eb64f4648a6f4211519a6c01e319c919515927 Mon Sep 17 00:00:00 2001 From: yoshihitoh Date: Tue, 15 Jan 2019 22:47:04 +0900 Subject: [PATCH] Fix error on toml parsing, deserialize to dedicated value type for each format. --- src/format.rs | 80 ++++++++++++++++++++++++++++++++-------------- src/format/json.rs | 2 ++ src/format/toml.rs | 2 ++ src/format/yaml.rs | 2 ++ 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/src/format.rs b/src/format.rs index 9bece18..81cbd5f 100644 --- a/src/format.rs +++ b/src/format.rs @@ -10,9 +10,6 @@ mod json; mod toml; mod yaml; -// NOTE: Use serde_json::Value as intermediate type, it keeps field orders, and have enough type to convert to another format. -type Value = serde_json::Value; - #[derive(Fail, Debug)] #[fail(display = "Unsupported format: {}", name)] struct UnsupportedFormatError { @@ -81,19 +78,32 @@ impl FormattedText { } pub fn convert_to(&self, format: Format) -> Result { - let value = self.deserialize(&self.text)?; - Self::serialize(format, &value).map(|s| FormattedText::new(format, s)) - } - - fn serialize(format: Format, v: &Value) -> Result { match format { - Format::Json => json::serialize(v), - Format::Toml => toml::serialize(v), - Format::Yaml => yaml::serialize(v), + Format::Json => self.to_json(), + Format::Toml => self.to_toml(), + Format::Yaml => self.to_yaml(), } + .map(|text| FormattedText { text, format }) + } + + fn to_json(&self) -> Result { + let value = self.deserialize::(&self.text)?; + json::serialize(&value) } - fn deserialize(&self, s: &str) -> Result { + fn to_toml(&self) -> Result { + let value = self.deserialize::(&self.text)?; + toml::serialize(&value) + } + fn to_yaml(&self) -> Result { + let value = self.deserialize::(&self.text)?; + yaml::serialize(&value) + } + + fn deserialize(&self, s: &str) -> Result + where + V: for<'de> serde::Deserialize<'de>, + { match self.format { Format::Json => json::deserialize(s), Format::Toml => toml::deserialize(s), @@ -116,15 +126,6 @@ mod tests { } }"#; - static TOML_TEXT: &'static str = r#"id = 123 -title = "Lorem ipsum dolor sit amet" - -[author] -id = 999 -first_name = "John" -last_name = "Doe" -"#; - static YAML_TEXT: &'static str = r#"--- id: 123 title: Lorem ipsum dolor sit amet @@ -162,7 +163,17 @@ author: // JSON => TOML let r = text.convert_to(Format::Toml); assert!(r.is_ok()); - assert_eq!(TOML_TEXT, r.as_ref().ok().unwrap().text); + assert_eq!( + r#"id = 123 +title = "Lorem ipsum dolor sit amet" + +[author] +first_name = "John" +id = 999 +last_name = "Doe" +"#, + r.as_ref().ok().unwrap().text + ); // JSON => YAML let r = text.convert_to(Format::Yaml); @@ -178,7 +189,18 @@ author: #[test] fn convert_toml() { - let text = FormattedText::new(Format::Toml, TOML_TEXT.to_string()); + let text = FormattedText::new( + Format::Toml, + r#"id = 123 +title = "Lorem ipsum dolor sit amet" + +[author] +id = 999 +first_name = "John" +last_name = "Doe" +"# + .to_string(), + ); // TOML => JSON let r = text.convert_to(Format::Json); @@ -209,7 +231,17 @@ author: // YAML => TOML let r = text.convert_to(Format::Toml); assert!(r.is_ok()); - assert_eq!(TOML_TEXT, r.as_ref().ok().unwrap().text); + assert_eq!( + r#"id = 123 +title = "Lorem ipsum dolor sit amet" + +[author] +first_name = "John" +id = 999 +last_name = "Doe" +"#, + r.as_ref().ok().unwrap().text + ); // Error // TODO: this test will be panicked on `r.is_err()`. need to survey why the panic occurs.. diff --git a/src/format/json.rs b/src/format/json.rs index f79d6ec..a524d6e 100644 --- a/src/format/json.rs +++ b/src/format/json.rs @@ -4,6 +4,8 @@ use serde::ser; use crate::errors::{self, ErrorKind}; +pub use serde_json::Value as InnerValue; + pub fn serialize(v: V) -> Result { Ok(serde_json::to_string_pretty(&v).context(ErrorKind::Serialization)?) } diff --git a/src/format/toml.rs b/src/format/toml.rs index db0605e..c7a7286 100644 --- a/src/format/toml.rs +++ b/src/format/toml.rs @@ -4,6 +4,8 @@ use serde::ser; use crate::errors::{self, ErrorKind}; +pub use toml::Value as InnerValue; + pub fn serialize(v: V) -> Result { Ok(toml::to_string(&v).context(ErrorKind::Serialization)?) } diff --git a/src/format/yaml.rs b/src/format/yaml.rs index 182d970..38cad6f 100644 --- a/src/format/yaml.rs +++ b/src/format/yaml.rs @@ -4,6 +4,8 @@ use serde::ser; use crate::errors::{self, ErrorKind}; +pub use serde_yaml::Value as InnerValue; + pub fn serialize(v: V) -> Result { Ok(serde_yaml::to_string(&v).context(ErrorKind::Serialization)?) }