From 1f6a404646da87482d0b843b08490ad80479a161 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Thu, 9 Jun 2022 12:11:02 +0900 Subject: [PATCH] ui: add function to recreate formatters with new color choice This allows us to reconfigure ui with the parsed --color option. I tried if implementing formatter.into_output() would make sense, and it turned out to be a bit mess as the Formatter trait doesn't know the lifetime of the underlying output. Ui could own the formatter behind Color|Plain enum variant in place of Box, but that seemed to unnecessarily change the Ui interface with little benefit. Since we just want to reinitialize the ui at very early stage, I think recreating the formatters is the simplest way to go. Regarding the formatter API, I have a feeling that Ui should keep the underlying stdout/stderr/color_map instead of the stateful formatters. ui.stdout_formatter() will return a temporary formatter, and maybe dropping it will automatically clear labels. This would also means the temporary formatter could be created with stdout.lock(). --- src/ui.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ui.rs b/src/ui.rs index 05e6b71e4..43aecf2c5 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -118,6 +118,23 @@ impl<'stdout> Ui<'stdout> { Ui::new(cwd, stdout, stderr, color, settings) } + /// Reconfigures the underlying outputs with the new color choice. + /// + /// It's up to caller to ensure that the current output formatters have no + /// labels applied. Otherwise the current color would persist. + pub fn reset_color_for_terminal(&mut self, choice: ColorChoice) { + let color = use_color(choice); + if self.color != color { + // it seems uneasy to unwrap the underlying output from the formatter, so + // recreate it. + let stdout_formatter = new_formatter(&self.settings, color, Box::new(io::stdout())); + let stderr_formatter = new_formatter(&self.settings, color, Box::new(io::stderr())); + self.color = color; + *self.stdout_formatter.get_mut().unwrap() = stdout_formatter; + *self.stderr_formatter.get_mut().unwrap() = stderr_formatter; + } + } + pub fn cwd(&self) -> &Path { &self.cwd }