Skip to content

Commit

Permalink
Fix error on toml parsing, deserialize to dedicated value type for ea…
Browse files Browse the repository at this point in the history
…ch format.
  • Loading branch information
yoshihitoh committed Jan 15, 2019
1 parent 5facfb6 commit 46eb64f
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 24 deletions.
80 changes: 56 additions & 24 deletions src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -81,19 +78,32 @@ impl FormattedText {
}

pub fn convert_to(&self, format: Format) -> Result<FormattedText, errors::Error> {
let value = self.deserialize(&self.text)?;
Self::serialize(format, &value).map(|s| FormattedText::new(format, s))
}

fn serialize(format: Format, v: &Value) -> Result<String, errors::Error> {
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<String, errors::Error> {
let value = self.deserialize::<json::InnerValue>(&self.text)?;
json::serialize(&value)
}

fn deserialize(&self, s: &str) -> Result<Value, errors::Error> {
fn to_toml(&self) -> Result<String, errors::Error> {
let value = self.deserialize::<toml::InnerValue>(&self.text)?;
toml::serialize(&value)
}
fn to_yaml(&self) -> Result<String, errors::Error> {
let value = self.deserialize::<yaml::InnerValue>(&self.text)?;
yaml::serialize(&value)
}

fn deserialize<V>(&self, s: &str) -> Result<V, errors::Error>
where
V: for<'de> serde::Deserialize<'de>,
{
match self.format {
Format::Json => json::deserialize(s),
Format::Toml => toml::deserialize(s),
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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..
Expand Down
2 changes: 2 additions & 0 deletions src/format/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use serde::ser;

use crate::errors::{self, ErrorKind};

pub use serde_json::Value as InnerValue;

pub fn serialize<V: ser::Serialize>(v: V) -> Result<String, errors::Error> {
Ok(serde_json::to_string_pretty(&v).context(ErrorKind::Serialization)?)
}
Expand Down
2 changes: 2 additions & 0 deletions src/format/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use serde::ser;

use crate::errors::{self, ErrorKind};

pub use toml::Value as InnerValue;

pub fn serialize<V: ser::Serialize>(v: V) -> Result<String, errors::Error> {
Ok(toml::to_string(&v).context(ErrorKind::Serialization)?)
}
Expand Down
2 changes: 2 additions & 0 deletions src/format/yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use serde::ser;

use crate::errors::{self, ErrorKind};

pub use serde_yaml::Value as InnerValue;

pub fn serialize<V: ser::Serialize>(v: V) -> Result<String, errors::Error> {
Ok(serde_yaml::to_string(&v).context(ErrorKind::Serialization)?)
}
Expand Down

0 comments on commit 46eb64f

Please sign in to comment.