From 3c5a9486cb84c0076ee12b7d40372f819a54ac05 Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Sun, 9 Jul 2017 14:38:48 -0600 Subject: add Settings struct --- src/ser.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/ser.rs b/src/ser.rs index 77db867..bf12278 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -137,6 +137,21 @@ pub enum Error { __Nonexhaustive, } +/// If given in `Settings` will result in a "pretty array" with the given settings +/// TODO: add better docs +#[derive(Debug, Default, Clone)] +pub struct ArraySettings { + indent: u64, +} + +/// Formatting Settings +/// TODO: add better docs +#[derive(Debug, Default, Clone)] +pub struct Settings { + array: Option, + pretty_string: bool, +} + /// Serialization implementation for TOML. /// /// This structure implements serialization support for TOML to serialize an @@ -149,6 +164,7 @@ pub enum Error { pub struct Serializer<'a> { dst: &'a mut String, state: State<'a>, + settings: Settings, } #[derive(Debug, Clone)] @@ -194,6 +210,7 @@ impl<'a> Serializer<'a> { Serializer { dst: dst, state: State::End, + settings: Settings::default(), } } @@ -591,6 +608,7 @@ impl<'a, 'b> ser::SerializeSeq for SerializeSeq<'a, 'b> { first: &self.first, type_: &self.type_, }, + settings: self.ser.settings.clone(), })?; self.first.set(false); Ok(()) @@ -650,6 +668,7 @@ impl<'a, 'b> ser::SerializeMap for SerializeTable<'a, 'b> { first: first, table_emitted: table_emitted, }, + settings: ser.settings.clone(), }); match res { Ok(()) => first.set(false), @@ -705,6 +724,7 @@ impl<'a, 'b> ser::SerializeStruct for SerializeTable<'a, 'b> { first: first, table_emitted: table_emitted, }, + settings: ser.settings.clone(), }); match res { Ok(()) => first.set(false), -- cgit v1.2.3 From 391cb61dffd51322bd310be7cba8641fe3398c19 Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Sun, 9 Jul 2017 14:58:48 -0600 Subject: add pretty sting serialization --- src/ser.rs | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ser.rs b/src/ser.rs index bf12278..d92b8a3 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -214,6 +214,22 @@ impl<'a> Serializer<'a> { } } + /// instantiate a "pretty" formatter + /// + /// TODO: add better docs + pub fn pretty(dst: &'a mut String) -> Serializer<'a> { + Serializer { + dst: dst, + state: State::End, + settings: Settings { + array: Some(ArraySettings { + indent: 4, + }), + pretty_string: true, + }, + } + } + fn display(&mut self, t: T, type_: &'static str) -> Result<(), Error> { @@ -300,12 +316,27 @@ impl<'a> Serializer<'a> { } fn emit_str(&mut self, value: &str) -> Result<(), Error> { - drop(write!(self.dst, "\"")); + let do_pretty = if self.settings.pretty_string { + value.contains('\n') + } else { + false + }; + if do_pretty { + drop(write!(self.dst, "'''\n")); + } else { + drop(write!(self.dst, "\"")); + } for ch in value.chars() { match ch { '\u{8}' => drop(write!(self.dst, "\\b")), '\u{9}' => drop(write!(self.dst, "\\t")), - '\u{a}' => drop(write!(self.dst, "\\n")), + '\u{a}' => { + if do_pretty { + drop(write!(self.dst, "\n")); + } else { + drop(write!(self.dst, "\\n")); + } + }, '\u{c}' => drop(write!(self.dst, "\\f")), '\u{d}' => drop(write!(self.dst, "\\r")), '\u{22}' => drop(write!(self.dst, "\\\"")), @@ -316,7 +347,11 @@ impl<'a> Serializer<'a> { ch => drop(write!(self.dst, "{}", ch)), } } - drop(write!(self.dst, "\"")); + if do_pretty { + drop(write!(self.dst, "'''")); + } else { + drop(write!(self.dst, "\"")); + } Ok(()) } -- cgit v1.2.3 From ffdafc4d361df0d6f6063af50863b7f87f4aa46a Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Sun, 9 Jul 2017 15:10:36 -0600 Subject: array doesn't break anything... --- src/ser.rs | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ser.rs b/src/ser.rs index d92b8a3..2bb9333 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -274,10 +274,24 @@ impl<'a> Serializer<'a> { } fn emit_array(&mut self, first: &Cell) -> Result<(), Error> { - if first.get() { - self.dst.push_str("["); - } else { - self.dst.push_str(", "); + match self.settings.array { + Some(ref a) => { + if first.get() { + self.dst.push_str("[\n") + } else { + self.dst.push_str(",\n") + } + for _ in 0..a.indent { + self.dst.push_str(" "); + } + }, + None => { + if first.get() { + self.dst.push_str("[") + } else { + self.dst.push_str(", ") + } + }, } Ok(()) } @@ -652,7 +666,13 @@ impl<'a, 'b> ser::SerializeSeq for SerializeSeq<'a, 'b> { fn end(self) -> Result<(), Error> { match self.type_.get() { Some("table") => return Ok(()), - Some(_) => self.ser.dst.push_str("]"), + Some(_) => { + if self.ser.settings.array.is_some() { + self.ser.dst.push_str("\n]"); + } else { + self.ser.dst.push_str("]"); + } + } None => { assert!(self.first.get()); self.ser.emit_key("array")?; -- cgit v1.2.3 From ae6096ab2611750fe44d3092b407d496ab94b0b9 Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Sun, 9 Jul 2017 15:20:29 -0600 Subject: pretty arrays --- src/ser.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ser.rs b/src/ser.rs index 2bb9333..4b4ac6e 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -142,6 +142,7 @@ pub enum Error { #[derive(Debug, Default, Clone)] pub struct ArraySettings { indent: u64, + trailing_comma: bool, } /// Formatting Settings @@ -224,6 +225,7 @@ impl<'a> Serializer<'a> { settings: Settings { array: Some(ArraySettings { indent: 4, + trailing_comma: true, }), pretty_string: true, }, @@ -667,10 +669,16 @@ impl<'a, 'b> ser::SerializeSeq for SerializeSeq<'a, 'b> { match self.type_.get() { Some("table") => return Ok(()), Some(_) => { - if self.ser.settings.array.is_some() { - self.ser.dst.push_str("\n]"); - } else { - self.ser.dst.push_str("]"); + match self.ser.settings.array { + Some(ref a) => { + if a.trailing_comma { + self.ser.dst.push_str(","); + } + self.ser.dst.push_str("\n]"); + }, + None => { + self.ser.dst.push_str("]"); + } } } None => { -- cgit v1.2.3 From 8e4813618556165542bf953140713f6dc71b62b8 Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Thu, 20 Jul 2017 12:47:51 -0600 Subject: use builder pattern --- src/ser.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ser.rs b/src/ser.rs index 4b4ac6e..2431737 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -137,18 +137,27 @@ pub enum Error { __Nonexhaustive, } -/// If given in `Settings` will result in a "pretty array" with the given settings -/// TODO: add better docs #[derive(Debug, Default, Clone)] -pub struct ArraySettings { - indent: u64, +#[doc(hidden)] +/// Internal place for holding array setings +struct ArraySettings { + indent: usize, trailing_comma: bool, } -/// Formatting Settings -/// TODO: add better docs +impl ArraySettings { + fn pretty() -> ArraySettings { + ArraySettings { + indent: 4, + trailing_comma: true, + } + } +} + #[derive(Debug, Default, Clone)] -pub struct Settings { +#[doc(hidden)] +/// Internal struct for holding serialization settings +struct Settings { array: Option, pretty_string: bool, } @@ -215,23 +224,72 @@ impl<'a> Serializer<'a> { } } - /// instantiate a "pretty" formatter - /// - /// TODO: add better docs + /// Instantiate a "pretty" formatter + /// + /// By default this will use : + /// - pretty strings + /// - arrays with an indentation of 4 and a trailing comma pub fn pretty(dst: &'a mut String) -> Serializer<'a> { Serializer { dst: dst, state: State::End, settings: Settings { - array: Some(ArraySettings { - indent: 4, - trailing_comma: true, - }), + array: Some(ArraySettings::pretty()), pretty_string: true, }, } } + /// Enable or Disable pretty strings + pub fn pretty_string(&mut self, value: bool) -> &mut Self { + self.settings.pretty_string = value; + self + } + + /// Enable or Disable pretty arrays + pub fn pretty_array(&mut self, value: bool) -> &mut Self { + self.settings.array = Some(if value { + ArraySettings::pretty() + } else { + ArraySettings::default() + }); + self + } + + /// Set the indent to value for pretty arrays + pub fn pretty_array_indent(&mut self, value: usize) -> &mut Self { + let use_default = if let &mut Some(ref mut a) = &mut self.settings.array { + a.indent = value; + false + } else { + true + }; + + if use_default { + let mut array = ArraySettings::pretty(); + array.indent = value; + self.settings.array = Some(array); + } + self + } + + /// Specify whether to use a trailing comma when serializing pretty arrays + pub fn pretty_array_trailing_comma(&mut self, value: bool) -> &mut Self { + let use_default = if let &mut Some(ref mut a) = &mut self.settings.array { + a.trailing_comma = value; + false + } else { + true + }; + + if use_default { + let mut array = ArraySettings::pretty(); + array.trailing_comma = value; + self.settings.array = Some(array); + } + self + } + fn display(&mut self, t: T, type_: &'static str) -> Result<(), Error> { -- cgit v1.2.3 From e0bc36051ad764a9032d88ce016b41f7214e4bc2 Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Fri, 21 Jul 2017 12:03:42 -0600 Subject: fix " --- src/ser.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ser.rs b/src/ser.rs index 2431737..283fee9 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -413,7 +413,13 @@ impl<'a> Serializer<'a> { }, '\u{c}' => drop(write!(self.dst, "\\f")), '\u{d}' => drop(write!(self.dst, "\\r")), - '\u{22}' => drop(write!(self.dst, "\\\"")), + '\u{22}' => { + if do_pretty { + drop(write!(self.dst, "\"")) + } else { + drop(write!(self.dst, "\\\"")) + } + }, '\u{5c}' => drop(write!(self.dst, "\\\\")), c if c < '\u{1f}' => { drop(write!(self.dst, "\\u{:04X}", ch as u32)) -- cgit v1.2.3 From 0adce506fa5ef2c5d6a545bc3a893d3a392829a3 Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Sat, 22 Jul 2017 15:11:23 -0600 Subject: fix docs and add --- src/lib.rs | 2 +- src/ser.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index ee4e961..c4a7e9d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,7 +161,7 @@ mod datetime; pub mod ser; #[doc(no_inline)] -pub use ser::{to_string, to_vec, Serializer}; +pub use ser::{to_string, to_string_pretty, to_vec, Serializer}; pub mod de; #[doc(no_inline)] pub use de::{from_slice, from_str, Deserializer}; diff --git a/src/ser.rs b/src/ser.rs index 283fee9..a267b3a 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -93,6 +93,18 @@ pub fn to_string(value: &T) -> Result Ok(dst) } +/// Serialize the given data structure as a "pretty" String of TOML. +/// +/// This is identical to `to_string` except the output string has a more +/// "pretty" output. See `Serializer::pretty` for more details. +pub fn to_string_pretty(value: &T) -> Result + where T: ser::Serialize, +{ + let mut dst = String::with_capacity(128); + value.serialize(&mut Serializer::pretty(&mut dst))?; + Ok(dst) +} + /// Errors that can occur when serializing a type. #[derive(Debug, PartialEq, Eq, Clone)] pub enum Error { @@ -226,9 +238,12 @@ impl<'a> Serializer<'a> { /// Instantiate a "pretty" formatter /// - /// By default this will use : - /// - pretty strings - /// - arrays with an indentation of 4 and a trailing comma + /// By default this will use: + /// + /// - pretty strings: strings with newlines will use the `'''` syntax. See + /// `Serializer::pretty_string` + /// - pretty arrays: each item in arrays will be on a newline, have an indentation of 4 and + /// have a trailing comma. See `Serializer::pretty_array` pub fn pretty(dst: &'a mut String) -> Serializer<'a> { Serializer { dst: dst, @@ -241,12 +256,59 @@ impl<'a> Serializer<'a> { } /// Enable or Disable pretty strings + /// + /// If enabled, strings with one or more newline character will use the `'''` syntax. + /// + /// # Examples + /// + /// Instead of: + /// + /// ```toml,no_run + /// single = "no newlines" + /// text = "\nfoo\nbar\n" + /// ``` + /// + /// You will have: + /// + /// ```toml,no_run + /// single = "no newlines" + /// text = ''' + /// foo + /// bar + /// ''' + /// ``` pub fn pretty_string(&mut self, value: bool) -> &mut Self { self.settings.pretty_string = value; self } /// Enable or Disable pretty arrays + /// + /// If enabled, arrays will always have each item on their own line. + /// + /// Some specific features can be controlled via other builder methods: + /// + /// - `Serializer::pretty_array_indent`: set the indent to a value other + /// than 4. + /// - `Serializer::pretty_array_trailing_comma`: enable/disable the trailing + /// comma on the last item. + /// + /// # Examples + /// + /// Instead of: + /// + /// ```toml,no_run + /// array = ["foo", "bar"] + /// ``` + /// + /// You will have: + /// + /// ```toml,no_run + /// array = [ + /// "foo", + /// "bar", + /// ] + /// ``` pub fn pretty_array(&mut self, value: bool) -> &mut Self { self.settings.array = Some(if value { ArraySettings::pretty() @@ -256,7 +318,9 @@ impl<'a> Serializer<'a> { self } - /// Set the indent to value for pretty arrays + /// Set the indent for pretty arrays + /// + /// See `Serializer::pretty_array` for more details. pub fn pretty_array_indent(&mut self, value: usize) -> &mut Self { let use_default = if let &mut Some(ref mut a) = &mut self.settings.array { a.indent = value; @@ -274,6 +338,8 @@ impl<'a> Serializer<'a> { } /// Specify whether to use a trailing comma when serializing pretty arrays + /// + /// See `Serializer::pretty_array` for more details. pub fn pretty_array_trailing_comma(&mut self, value: bool) -> &mut Self { let use_default = if let &mut Some(ref mut a) = &mut self.settings.array { a.trailing_comma = value; -- cgit v1.2.3 From 8b7e1b69ad654cdbd7e2120e49e4d75d02f0a695 Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Mon, 24 Jul 2017 09:18:47 -0600 Subject: use ignore rather than no_run for toml blocks --- src/ser.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ser.rs b/src/ser.rs index a267b3a..fb9f424 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -263,14 +263,14 @@ impl<'a> Serializer<'a> { /// /// Instead of: /// - /// ```toml,no_run + /// ```ignore /// single = "no newlines" /// text = "\nfoo\nbar\n" /// ``` /// /// You will have: /// - /// ```toml,no_run + /// ```ignore /// single = "no newlines" /// text = ''' /// foo @@ -297,13 +297,13 @@ impl<'a> Serializer<'a> { /// /// Instead of: /// - /// ```toml,no_run + /// ```ignore /// array = ["foo", "bar"] /// ``` /// /// You will have: /// - /// ```toml,no_run + /// ```ignore /// array = [ /// "foo", /// "bar", -- cgit v1.2.3 From 766b27e902bf4fc49f131443cd5a247c73cd4e72 Mon Sep 17 00:00:00 2001 From: Garrett Berg Date: Mon, 24 Jul 2017 09:46:24 -0600 Subject: fix Serializer::pretty_array(false) --- src/ser.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ser.rs b/src/ser.rs index fb9f424..863bd75 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -310,11 +310,11 @@ impl<'a> Serializer<'a> { /// ] /// ``` pub fn pretty_array(&mut self, value: bool) -> &mut Self { - self.settings.array = Some(if value { - ArraySettings::pretty() + self.settings.array = if value { + Some(ArraySettings::pretty()) } else { - ArraySettings::default() - }); + None + }; self } -- cgit v1.2.3