From 894bfcd71e4e198406b038538fcfb02058e85e97 Mon Sep 17 00:00:00 2001 From: Jon Thacker Date: Wed, 30 Dec 2020 18:49:07 -0500 Subject: [PATCH] Add suffix customization to default formatter. This defaults to the same suffix as before, \n. Supports several use cases: * When writing to a raw TTY, \r\n is required * Custom formatting of messages may be desirable, e.g. \n\n --- src/fmt/mod.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++--- src/lib.rs | 6 +++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/fmt/mod.rs b/src/fmt/mod.rs index 558c4d9d..3c4fee0a 100644 --- a/src/fmt/mod.rs +++ b/src/fmt/mod.rs @@ -144,6 +144,7 @@ pub(crate) struct Builder { pub format_level: bool, pub format_indent: Option, pub custom_format: Option, + pub format_suffix: &'static str, built: bool, } @@ -155,6 +156,7 @@ impl Default for Builder { format_level: true, format_indent: Some(4), custom_format: None, + format_suffix: "\n", built: false, } } @@ -187,6 +189,7 @@ impl Builder { level: built.format_level, written_header_value: false, indent: built.format_indent, + suffix: built.format_suffix, buf, }; @@ -211,6 +214,7 @@ struct DefaultFormat<'a> { written_header_value: bool, indent: Option, buf: &'a mut Formatter, + suffix: &'a str, } impl<'a> DefaultFormat<'a> { @@ -319,7 +323,7 @@ impl<'a> DefaultFormat<'a> { fn write_args(&mut self, record: &Record) -> io::Result<()> { match self.indent { // Fast path for no indentation - None => writeln!(self.buf, "{}", record.args()), + None => write!(self.buf, "{}{}", record.args(), self.suffix), Some(indent_count) => { // Create a wrapper around the buffer only if we have to actually indent the message @@ -334,7 +338,13 @@ impl<'a> DefaultFormat<'a> { let mut first = true; for chunk in buf.split(|&x| x == b'\n') { if !first { - write!(self.fmt.buf, "\n{:width$}", "", width = self.indent_count)?; + write!( + self.fmt.buf, + "{}{:width$}", + self.fmt.suffix, + "", + width = self.indent_count + )?; } self.fmt.buf.write_all(chunk)?; first = false; @@ -357,7 +367,7 @@ impl<'a> DefaultFormat<'a> { write!(wrapper, "{}", record.args())?; } - writeln!(self.buf)?; + write!(self.buf, "{}", self.suffix)?; Ok(()) } @@ -402,6 +412,7 @@ mod tests { level: true, written_header_value: false, indent: None, + suffix: "\n", buf: &mut f, }); @@ -422,6 +433,7 @@ mod tests { level: false, written_header_value: false, indent: None, + suffix: "\n", buf: &mut f, }); @@ -442,6 +454,7 @@ mod tests { level: true, written_header_value: false, indent: Some(4), + suffix: "\n", buf: &mut f, }); @@ -462,6 +475,7 @@ mod tests { level: true, written_header_value: false, indent: Some(0), + suffix: "\n", buf: &mut f, }); @@ -482,9 +496,52 @@ mod tests { level: false, written_header_value: false, indent: Some(4), + suffix: "\n", buf: &mut f, }); assert_eq!("log\n message\n", written); } + + #[test] + fn format_suffix() { + let writer = writer::Builder::new() + .write_style(WriteStyle::Never) + .build(); + + let mut f = Formatter::new(&writer); + + let written = write(DefaultFormat { + timestamp: None, + module_path: false, + level: false, + written_header_value: false, + indent: None, + suffix: "\n\n", + buf: &mut f, + }); + + assert_eq!("log\nmessage\n\n", written); + } + + #[test] + fn format_suffix_with_indent() { + let writer = writer::Builder::new() + .write_style(WriteStyle::Never) + .build(); + + let mut f = Formatter::new(&writer); + + let written = write(DefaultFormat { + timestamp: None, + module_path: false, + level: false, + written_header_value: false, + indent: Some(4), + suffix: "\n\n", + buf: &mut f, + }); + + assert_eq!("log\n\n message\n\n", written); + } } diff --git a/src/lib.rs b/src/lib.rs index 53afe7e1..494ccb1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -632,6 +632,12 @@ impl Builder { self.format_timestamp(Some(fmt::TimestampPrecision::Nanos)) } + /// Configures the end of line suffix. + pub fn format_suffix(&mut self, suffix: &'static str) -> &mut Self { + self.format.format_suffix = suffix; + self + } + /// Adds a directive to the filter for a specific module. /// /// # Examples