aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ser.rs79
-rw-r--r--tests/pretty.rs44
2 files changed, 112 insertions, 11 deletions
diff --git a/src/ser.rs b/src/ser.rs
index 3c4c220..ef037ed 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -169,9 +169,19 @@ impl ArraySettings {
#[doc(hidden)]
#[derive(Debug, Default, Clone)]
-/// String settings. Currently empty but may contain settings
-/// eventually.
-struct StringSettings();
+/// String settings
+struct StringSettings {
+ /// Whether to use literal strings when possible
+ literal: bool,
+}
+
+impl StringSettings {
+ fn pretty() -> StringSettings {
+ StringSettings {
+ literal: true,
+ }
+ }
+}
#[derive(Debug, Default, Clone)]
#[doc(hidden)]
@@ -259,7 +269,7 @@ impl<'a> Serializer<'a> {
state: State::End,
settings: Rc::new(Settings {
array: Some(ArraySettings::pretty()),
- string: Some(StringSettings()),
+ string: Some(StringSettings::pretty()),
}),
}
}
@@ -289,13 +299,56 @@ impl<'a> Serializer<'a> {
/// ```
pub fn pretty_string(&mut self, value: bool) -> &mut Self {
Rc::get_mut(&mut self.settings).unwrap().string = if value {
- Some(StringSettings())
+ Some(StringSettings::pretty())
} else {
None
};
self
}
+ /// Enable or Disable Literal strings for pretty strings
+ ///
+ /// If enabled, literal strings will be used when possible and strings with
+ /// one or more newlines will use triple quotes (i.e.: `'''` or `"""`)
+ ///
+ /// If disabled, literal strings will NEVER be used and strings with one or
+ /// more newlines will use `"""`
+ ///
+ /// # Examples
+ ///
+ /// Instead of:
+ ///
+ /// ```toml,ignore
+ /// single = "no newlines"
+ /// text = "\nfoo\nbar\n"
+ /// ```
+ ///
+ /// You will have:
+ ///
+ /// ```toml,ignore
+ /// single = "no newlines"
+ /// text = """
+ /// foo
+ /// bar
+ /// """
+ /// ```
+ pub fn pretty_string_literal(&mut self, value: bool) -> &mut Self {
+ let use_default = if let &mut Some(ref mut s) = &mut Rc::get_mut(&mut self.settings)
+ .unwrap().string {
+ s.literal = value;
+ false
+ } else {
+ true
+ };
+
+ if use_default {
+ let mut string = StringSettings::pretty();
+ string.literal = value;
+ Rc::get_mut(&mut self.settings).unwrap().string = Some(string);
+ }
+ self
+ }
+
/// Enable or Disable pretty arrays
///
/// If enabled, arrays will always have each item on their own line.
@@ -548,7 +601,11 @@ impl<'a> Serializer<'a> {
}
let repr = if !is_key && self.settings.string.is_some() {
- do_pretty(value)
+ match (&self.settings.string, do_pretty(value)) {
+ (&Some(StringSettings { literal: false, .. }), Repr::Literal(_, ty)) =>
+ Repr::Std(ty),
+ (_, r @ _) => r,
+ }
} else {
Repr::Std(Type::OnelineSingle)
};
@@ -569,8 +626,11 @@ impl<'a> Serializer<'a> {
Repr::Std(ty) => {
match ty {
Type::NewlineTripple => self.dst.push_str("\"\"\"\n"),
- Type::OnelineSingle => self.dst.push('"'),
- _ => unreachable!(),
+ // note: OnelineTripple can happen if do_pretty wants to do
+ // '''it's one line'''
+ // but settings.string.literal == false
+ Type::OnelineSingle |
+ Type::OnelineTripple => self.dst.push('"'),
}
for ch in value.chars() {
match ch {
@@ -593,8 +653,7 @@ impl<'a> Serializer<'a> {
}
match ty {
Type::NewlineTripple => self.dst.push_str("\"\"\""),
- Type::OnelineSingle => self.dst.push('"'),
- _ => unreachable!(),
+ Type::OnelineSingle | Type::OnelineTripple => self.dst.push('"'),
}
},
}
diff --git a/tests/pretty.rs b/tests/pretty.rs
index 3a9777c..ce906d9 100644
--- a/tests/pretty.rs
+++ b/tests/pretty.rs
@@ -198,7 +198,7 @@ text = """
this is the first line.
This has a ''' in it and \"\"\" cuz it's tricky yo
Also ' and \" because why not
-this is the third line
+this is the fourth line
"""
"##;
@@ -260,3 +260,45 @@ fn table_array() {
println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result);
}
+
+// FIXME: add the `glass` line to this. Unfortunately there seems to
+// be an issue with the deserialization module that treats the first \n
+// as a real newline in that case (not cool)
+const PRETTY_TRICKY_NON_LITERAL: &'static str = r##"[example]
+f = "\f"
+plain = """
+This has a couple of lines
+Because it likes to.
+"""
+r = "\r"
+r_newline = """
+\r
+"""
+single = "this is a single line but has '' cuz it's tricky"
+single_tricky = "single line with ''' in it"
+tabs = """
+this is pretty standard
+\texcept for some \ttabs right here
+"""
+text = """
+this is the first line.
+This has a ''' in it and \"\"\" cuz it's tricky yo
+Also ' and \" because why not
+this is the fourth line
+"""
+"##;
+
+#[test]
+fn pretty_tricky_non_literal() {
+ let toml = PRETTY_TRICKY_NON_LITERAL;
+ let value: toml::Value = toml::from_str(toml).unwrap();
+ let mut result = String::with_capacity(128);
+ {
+ let mut serializer = toml::Serializer::pretty(&mut result);
+ serializer.pretty_string_literal(false);
+ value.serialize(&mut serializer).unwrap();
+ }
+ println!("EXPECTED:\n{}", toml);
+ println!("\nRESULT:\n{}", result);
+ assert_eq!(toml, &result);
+}