From 4b63096153e4418c16cfa742bb34fb6ad25db7f5 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 14 May 2019 16:40:11 +1000 Subject: [PATCH] Add `escape_all_strings` to `Emitter` This ensures typing between loading an emitting. --- src/emitter.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/emitter.rs b/src/emitter.rs index 09e9f876..c695af13 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -41,6 +41,7 @@ pub struct YamlEmitter<'a> { writer: &'a mut fmt::Write, best_indent: usize, compact: bool, + escape_all_strings: bool, level: isize, } @@ -117,6 +118,7 @@ impl<'a> YamlEmitter<'a> { best_indent: 2, compact: true, level: -1, + escape_all_strings: false, } } @@ -137,6 +139,19 @@ impl<'a> YamlEmitter<'a> { self.compact } + /// Wrap all `YAML::String` nodes in double-quotes and escape special characters (if any), + /// regardless of whether or not they contain special characters. + /// + /// This maintains typing, ensuring that `example: "0x00"` is not emitted as `example: 0x00`. + pub fn escape_all_strings(&mut self, escape_all_strings: bool) { + self.escape_all_strings = escape_all_strings + } + + /// Determine if this emitter will wrap all strings in double-quotes. + pub fn is_escape_all_strings(&self) -> bool { + self.escape_all_strings + } + pub fn dump(&mut self, doc: &Yaml) -> EmitResult { // write DocumentStart writeln!(self.writer, "---")?; @@ -161,7 +176,7 @@ impl<'a> YamlEmitter<'a> { Yaml::Array(ref v) => self.emit_array(v), Yaml::Hash(ref h) => self.emit_hash(h), Yaml::String(ref v) => { - if need_quotes(v) { + if need_quotes(v) | self.escape_all_strings { escape_str(self.writer, v)?; } else { write!(self.writer, "{}", v)?; @@ -638,4 +653,40 @@ a: assert_eq!(s, writer); } + #[test] + fn test_escape_all_strings() { + let s = r#"--- +example: "0x00""#; + + let docs = YamlLoader::load_from_str(&s).unwrap(); + let doc = &docs[0]; + + let mut wr = String::new(); + { + let mut emitter = YamlEmitter::new(&mut wr); + assert_eq!(emitter.is_escape_all_strings(), false); + emitter.dump(doc).unwrap(); + } + + assert_eq!( + wr, + r#"--- +example: 0x00"# + ); + + let mut wr = String::new(); + { + let mut emitter = YamlEmitter::new(&mut wr); + emitter.escape_all_strings(true); + assert_eq!(emitter.is_escape_all_strings(), true); + emitter.dump(doc).unwrap(); + } + + assert_eq!( + wr, + r#"--- +"example": "0x00""# + ); + } + }