From d601290332c1565e2a719d148f953a39a65a5d87 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 11 Oct 2017 14:37:57 -0400 Subject: [PATCH 1/2] Pretty configuration --- Cargo.toml | 2 +- examples/encode.rs | 24 +++++++--- src/ser/mod.rs | 107 ++++++++++++++++++++++++++++++++++----------- src/ser/pretty.rs | 16 +++---- 4 files changed, 106 insertions(+), 43 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ca473635..e5d9266e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ron" -version = "0.1.3" +version = "0.1.4" license = "MIT/Apache-2.0" keywords = ["parser", "serde", "serialization"] authors = [ diff --git a/examples/encode.rs b/examples/encode.rs index 20336710..8523e7d3 100644 --- a/examples/encode.rs +++ b/examples/encode.rs @@ -3,19 +3,23 @@ extern crate ron; extern crate serde_derive; use std::collections::HashMap; +use std::default::Default; use std::fs::File; -use ron::ser::pretty::to_string; +use ron::ser::{PrettyConfig, to_string_pretty}; #[derive(Serialize)] struct Config { - boolean: bool, - float: f32, + float: (f32, f64), + tuple: TupleStruct, map: HashMap, nested: Nested, var: Variant, } +#[derive(Serialize)] +struct TupleStruct((), bool); + #[derive(Serialize)] enum Variant { A(u8, &'static str), @@ -33,16 +37,22 @@ fn main() { let mut file = File::create("config.ron").expect("Failed to create file"); - let s = to_string(&Config { - boolean: false, - float: 2.18, + let data = Config { + float: (2.18, -1.1), + tuple: TupleStruct((), false), map: HashMap::from_iter(vec![(0, '1'), (1, '2'), (3, '5'), (8, '1')]), nested: Nested { a: "Hello from \"RON\"".to_string(), b: 'b', }, var: Variant::A(!0, ""), - }).expect("Serialization failed"); + }; + + let pretty = PrettyConfig { + separate_tuple_members: true, + .. PrettyConfig::default() + }; + let s = to_string_pretty(&data, pretty).expect("Serialization failed"); file.write(s.as_bytes()).expect("Failed to write data to file"); } diff --git a/src/ser/mod.rs b/src/ser/mod.rs index 49ed1724..152e879d 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -1,18 +1,13 @@ use std::error::Error as StdError; +use std::result::Result as StdResult; use std::fmt::{Display, Formatter, Result as FmtResult}; use serde::ser::{self, Serialize}; +#[deprecated(since="0.1.4", note="please use `to_string_pretty` with `PrettyConfig::default()` instead")] pub mod pretty; - mod value; -#[cfg(not(target_os = "windows"))] -const NEWLINE: &str = "\n"; - -#[cfg(target_os = "windows")] -const NEWLINE: &str = "\r\n"; - /// Serializes `value` and returns it as string. /// /// This function does not generate any newlines or nice formatting; @@ -29,8 +24,21 @@ pub fn to_string(value: &T) -> Result Ok(s.output) } +/// Serializes `value` in the recommended RON layout in a pretty way. +pub fn to_string_pretty(value: &T, config: PrettyConfig) -> Result + where T: Serialize +{ + let mut s = Serializer { + output: String::new(), + pretty: Some((config, Pretty { indent: 0 })), + struct_names: false, + }; + value.serialize(&mut s)?; + Ok(s.output) +} + /// Serialization result. -pub type Result = ::std::result::Result; +pub type Result = StdResult; /// Serialization error. #[derive(Clone, Debug, PartialEq)] @@ -61,38 +69,69 @@ impl StdError for Error { } } +/// Pretty serializer state struct Pretty { indent: usize, } +/// Pretty serializer configuration +#[derive(Clone, Debug)] +pub struct PrettyConfig { + /// New line string + pub new_line: String, + /// Indentation string + pub indentor: String, + /// Separate tuple members with indentation + pub separate_tuple_members: bool, +} + +impl Default for PrettyConfig { + fn default() -> Self { + PrettyConfig { + #[cfg(not(target_os = "windows"))] + new_line: "\n".to_string(), + #[cfg(target_os = "windows")] + new_line: "\r\n".to_string(), + indentor: " ".to_string(), + separate_tuple_members: false, + } + } +} + /// The RON serializer. /// /// You can just use `to_string` for deserializing a value. /// If you want it pretty-printed, take a look at the `pretty` module. pub struct Serializer { output: String, - pretty: Option, + pretty: Option<(PrettyConfig, Pretty)>, struct_names: bool, } impl Serializer { + fn separate_tuple_members(&self) -> bool { + self.pretty.as_ref() + .map(|&(ref config, _)| config.separate_tuple_members) + .unwrap_or(false) + } + fn start_indent(&mut self) { - if let Some(ref mut pretty) = self.pretty { + if let Some((ref config, ref mut pretty)) = self.pretty { pretty.indent += 1; - self.output += NEWLINE; + self.output += &config.new_line; } } fn indent(&mut self) { - if let Some(ref pretty) = self.pretty { - self.output.extend((0..pretty.indent * 4).map(|_| " ")); + if let Some((ref config, ref pretty)) = self.pretty { + self.output.extend((0..pretty.indent).map(|_| config.indentor.as_str())); } } fn end_indent(&mut self) { - if let Some(ref mut pretty) = self.pretty { + if let Some((ref config, ref mut pretty)) = self.pretty { pretty.indent -= 1; - self.output.extend((0..pretty.indent * 4).map(|_| " ")); + self.output.extend((0..pretty.indent).map(|_| config.indentor.as_str())); } } } @@ -256,7 +295,9 @@ impl<'a> ser::Serializer for &'a mut Serializer { { self.output += variant; self.output += "("; + value.serialize(&mut *self)?; + self.output += ")"; Ok(()) } @@ -272,6 +313,10 @@ impl<'a> ser::Serializer for &'a mut Serializer { fn serialize_tuple(self, _: usize) -> Result { self.output += "("; + if self.separate_tuple_members() { + self.start_indent(); + } + Ok(self) } @@ -297,6 +342,10 @@ impl<'a> ser::Serializer for &'a mut Serializer { self.output += variant; self.output += "("; + if self.separate_tuple_members() { + self.start_indent(); + } + Ok(self) } @@ -351,8 +400,8 @@ impl<'a> ser::SerializeSeq for &'a mut Serializer { value.serialize(&mut **self)?; self.output += ","; - if self.pretty.is_some() { - self.output += NEWLINE; + if let Some((ref config, _)) = self.pretty { + self.output += &config.new_line; } Ok(()) @@ -373,11 +422,15 @@ impl<'a> ser::SerializeTuple for &'a mut Serializer { fn serialize_element(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize { + if self.separate_tuple_members() { + self.indent(); + } + value.serialize(&mut **self)?; self.output += ","; - if self.pretty.is_some() { - self.output += " "; + if let Some((ref config, _)) = self.pretty { + self.output += if self.separate_tuple_members() { &config.new_line } else { " " }; } Ok(()) @@ -385,8 +438,12 @@ impl<'a> ser::SerializeTuple for &'a mut Serializer { fn end(self) -> Result<()> { if self.pretty.is_some() { - self.output.pop(); - self.output.pop(); + if self.separate_tuple_members() { + self.end_indent(); + } else { + self.output.pop(); + self.output.pop(); + } } self.output += ")"; @@ -450,8 +507,8 @@ impl<'a> ser::SerializeMap for &'a mut Serializer { value.serialize(&mut **self)?; self.output += ","; - if self.pretty.is_some() { - self.output += NEWLINE; + if let Some((ref config, _)) = self.pretty { + self.output += &config.new_line; } Ok(()) @@ -484,8 +541,8 @@ impl<'a> ser::SerializeStruct for &'a mut Serializer { value.serialize(&mut **self)?; self.output += ","; - if self.pretty.is_some() { - self.output += NEWLINE; + if let Some((ref config, _)) = self.pretty { + self.output += &config.new_line; } Ok(()) diff --git a/src/ser/pretty.rs b/src/ser/pretty.rs index f4db9da0..b4c27395 100644 --- a/src/ser/pretty.rs +++ b/src/ser/pretty.rs @@ -1,18 +1,14 @@ -//! Provides pretty serialization with `to_string`. +//! Provides default pretty serialization with `to_string`. -use super::{Pretty, Result, Serializer}; +use super::{Result, to_string_pretty}; use serde::ser::Serialize; +use std::default::Default; -/// Serializes `value` in the recommended RON layout. +/// Serializes `value` in the recommended RON layout with +/// default pretty configuration. pub fn to_string(value: &T) -> Result where T: Serialize { - let mut s = Serializer { - output: String::new(), - pretty: Some(Pretty { indent: 0 }), - struct_names: false, - }; - value.serialize(&mut s)?; - Ok(s.output) + to_string_pretty(value, Default::default()) } From ed7904605d4306e2a7c41baf2a9787e872b282cc Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 12 Oct 2017 08:59:05 -0400 Subject: [PATCH 2/2] Using serde_derive unconditionally --- Cargo.toml | 3 +-- examples/decode.rs | 2 +- examples/decode_file.rs | 2 +- examples/encode.rs | 2 +- src/lib.rs | 4 +--- src/ser/mod.rs | 2 +- tests/roundtrip.rs | 2 +- 7 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e5d9266e..d2b05ba2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,8 +18,7 @@ exclude = ["bors.toml", ".travis.yml"] name = "ron" [dependencies] -serde = "1" +serde = { version = "1", features = ["serde_derive"] } [dev-dependencies] -serde_derive = "1" serde_json = "1" diff --git a/examples/decode.rs b/examples/decode.rs index 2a6da8b6..94aaf064 100644 --- a/examples/decode.rs +++ b/examples/decode.rs @@ -1,6 +1,6 @@ extern crate ron; #[macro_use] -extern crate serde_derive; +extern crate serde; use std::collections::HashMap; diff --git a/examples/decode_file.rs b/examples/decode_file.rs index e0868482..f34e0f5e 100644 --- a/examples/decode_file.rs +++ b/examples/decode_file.rs @@ -1,6 +1,6 @@ extern crate ron; #[macro_use] -extern crate serde_derive; +extern crate serde; use std::collections::HashMap; use std::fs::File; diff --git a/examples/encode.rs b/examples/encode.rs index 8523e7d3..bae7b20c 100644 --- a/examples/encode.rs +++ b/examples/encode.rs @@ -1,6 +1,6 @@ extern crate ron; #[macro_use] -extern crate serde_derive; +extern crate serde; use std::collections::HashMap; use std::default::Default; diff --git a/src/lib.rs b/src/lib.rs index e7222e87..070793e9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,10 +57,8 @@ Serializing / Deserializing is as simple as calling `to_string` / `from_str`. !*/ -extern crate serde; -#[cfg(test)] #[macro_use] -extern crate serde_derive; +extern crate serde; pub mod de; pub mod ser; diff --git a/src/ser/mod.rs b/src/ser/mod.rs index 152e879d..a7710788 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -75,7 +75,7 @@ struct Pretty { } /// Pretty serializer configuration -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct PrettyConfig { /// New line string pub new_line: String, diff --git a/tests/roundtrip.rs b/tests/roundtrip.rs index 35af8668..c88b9f48 100644 --- a/tests/roundtrip.rs +++ b/tests/roundtrip.rs @@ -1,6 +1,6 @@ extern crate ron; #[macro_use] -extern crate serde_derive; +extern crate serde; use std::collections::HashMap;