diff --git a/src/config.rs b/src/config.rs index 5f5196ef..d01c3ebb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -58,6 +58,26 @@ pub(crate) enum TimeFormat { Custom(&'static [time::format_description::FormatItem<'static>]), } +/// UTF-8 end of line character sequences +pub enum LineEnding { + /// Line feed + LF, + /// Carriage return + CR, + /// Carriage return + Line feed + Crlf, + /// Vertical tab + VT, + /// Form feed + FF, + /// Next line + Nel, + /// Line separator + LS, + /// Paragraph separator + PS, +} + /// Configuration for the Loggers /// /// All loggers print the message in the following form: @@ -89,6 +109,7 @@ pub struct Config { pub(crate) write_log_enable_colors: bool, #[cfg(feature = "paris")] pub(crate) enable_paris_formatting: bool, + pub(crate) line_ending: String, } impl Config { @@ -121,6 +142,21 @@ impl ConfigBuilder { ConfigBuilder(Config::default()) } + /// Set a custom line ending + pub fn set_line_ending(&mut self, line_ending: LineEnding) -> &mut ConfigBuilder { + match line_ending { + LineEnding::LF => self.0.line_ending = String::from("\u{000A}"), + LineEnding::CR => self.0.line_ending = String::from("\u{000D}"), + LineEnding::Crlf => self.0.line_ending = String::from("\u{000D}\u{000A}"), + LineEnding::VT => self.0.line_ending = String::from("\u{000B}"), + LineEnding::FF => self.0.line_ending = String::from("\u{000C}"), + LineEnding::Nel => self.0.line_ending = String::from("\u{0085}"), + LineEnding::LS => self.0.line_ending = String::from("\u{2028}"), + LineEnding::PS => self.0.line_ending = String::from("\u{2029}"), + } + self + } + /// Set at which level and above (more verbose) the level itself shall be logged (default is Error) pub fn set_max_level(&mut self, level: LevelFilter) -> &mut ConfigBuilder { self.0.level = level; @@ -368,6 +404,7 @@ impl Default for Config { #[cfg(feature = "paris")] enable_paris_formatting: true, + line_ending: String::from("\u{000A}"), } } } diff --git a/src/loggers/logging.rs b/src/loggers/logging.rs index 47bc99ff..4366ba87 100644 --- a/src/loggers/logging.rs +++ b/src/loggers/logging.rs @@ -62,9 +62,14 @@ where } #[cfg(feature = "paris")] - return write_args(record, write, config.enable_paris_formatting); + return write_args( + record, + write, + config.enable_paris_formatting, + &config.line_ending, + ); #[cfg(not(feature = "paris"))] - return write_args(record, write); + return write_args(record, write, &config.line_ending); } #[inline(always)] @@ -227,28 +232,34 @@ where #[inline(always)] #[cfg(feature = "paris")] -pub fn write_args(record: &Record<'_>, write: &mut W, with_colors: bool) -> Result<(), Error> +pub fn write_args( + record: &Record<'_>, + write: &mut W, + with_colors: bool, + line_ending: &str, +) -> Result<(), Error> where W: Write + Sized, { - writeln!( + write!( write, - "{}", + "{}{}", crate::__private::paris::formatter::format_string( format!("{}", record.args()), with_colors - ) + ), + line_ending )?; Ok(()) } #[inline(always)] #[cfg(not(feature = "paris"))] -pub fn write_args(record: &Record<'_>, write: &mut W) -> Result<(), Error> +pub fn write_args(record: &Record<'_>, write: &mut W, line_ending: &str) -> Result<(), Error> where W: Write + Sized, { - writeln!(write, "{}", record.args())?; + write!(write, "{}{}", record.args(), line_ending)?; Ok(()) } diff --git a/src/loggers/termlog.rs b/src/loggers/termlog.rs index 1858d235..460c36e6 100644 --- a/src/loggers/termlog.rs +++ b/src/loggers/termlog.rs @@ -176,9 +176,14 @@ impl TermLogger { } #[cfg(feature = "paris")] - write_args(record, term_lock, self.config.enable_paris_formatting)?; + write_args( + record, + term_lock, + self.config.enable_paris_formatting, + &self.config.line_ending, + )?; #[cfg(not(feature = "paris"))] - write_args(record, term_lock)?; + write_args(record, term_lock, &self.config.line_ending)?; // The log crate holds the logger as a `static mut`, which isn't dropped // at program exit: https://doc.rust-lang.org/reference/items/static-items.html