From fd01e0730495892ddd59eb7e21a8ed5f7c1d9df8 Mon Sep 17 00:00:00 2001 From: Joshua Megnauth <48846352+joshuamegnauth54@users.noreply.github.com> Date: Tue, 18 Nov 2025 15:29:56 -0500 Subject: [PATCH] fix(time): handle invalid strftime formatters Invalid format strings trigger a panic for the strftime formatter's Display implementation. This can occur frequently when the user is inputting a format string in COSMIC Settings. A plain '%' immediately causes a panic. This commit handles invalid formatters correctly by writing to a buffer instead of relying on to_string() (Display). --- cosmic-applet-time/src/window.rs | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/cosmic-applet-time/src/window.rs b/cosmic-applet-time/src/window.rs index 04d05590..0583c03e 100644 --- a/cosmic-applet-time/src/window.rs +++ b/cosmic-applet-time/src/window.rs @@ -163,13 +163,27 @@ impl Window { calendar } + /// Format with strftime if non-empty and ignore errors. + /// + /// Do not use to_string(). The formatter panics on invalid specifiers. + fn maybe_strftime(&self) -> Option { + // strftime may override locale specific elements so it stands alone rather + // than using ICU. + (!self.config.format_strftime.is_empty()) + .then(|| { + let mut s = String::new(); + self.now + .format(&self.config.format_strftime) + .write_to(&mut s) + .map(|_| s) + .ok() + }) + .flatten() + } + fn vertical_layout(&self) -> Element<'_, Message> { - let elements: Vec> = if !self.config.format_strftime.is_empty() { - // strftime formatter may override locale specific elements so it stands alone rather - // than using ICU to determine a format. - self.now - .format(&self.config.format_strftime) - .to_string() + let elements: Vec> = if let Some(strftime) = self.maybe_strftime() { + strftime .split_whitespace() .map(|piece| self.core.applet.text(piece.to_owned()).into()) .collect() @@ -235,8 +249,8 @@ impl Window { } fn horizontal_layout(&self) -> Element<'_, Message> { - let formatted_date = if !self.config.format_strftime.is_empty() { - self.now.format(&self.config.format_strftime).to_string() + let formatted_date = if let Some(strftime) = self.maybe_strftime() { + strftime } else { let datetime = self.create_datetime(&self.now); let mut prefs = DateTimeFormatterPreferences::from(self.locale.clone());