From 209b2cd853ea996cb7173a8c55ab1b110472fc68 Mon Sep 17 00:00:00 2001 From: Max Verevkin <34583604+MaxVerevkin@users.noreply.github.com> Date: Sun, 7 Apr 2024 19:30:12 +0300 Subject: [PATCH] map! macro: add @extend mode to extend an existing map (#2040) This avoids creating a temporary hashmap. --- src/blocks/privacy.rs | 20 ++++++++++---------- src/blocks/weather.rs | 17 ++++++++--------- src/util.rs | 26 +++++++++++++++----------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/blocks/privacy.rs b/src/blocks/privacy.rs index 14add4d6a..b5afcee52 100644 --- a/src/blocks/privacy.rs +++ b/src/blocks/privacy.rs @@ -209,34 +209,34 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> { let mut values = Values::new(); if let Some(info_by_type) = info.get(&Type::Audio) { - values.extend(map! { + map! { @extend values "icon_audio" => Value::icon("microphone"), "info_audio" => Value::text(format!("{}", info_by_type)) - }); + } } if let Some(info_by_type) = info.get(&Type::AudioSink) { - values.extend(map! { + map! { @extend values "icon_audio_sink" => Value::icon("volume"), "info_audio_sink" => Value::text(format!("{}", info_by_type)) - }); + } } if let Some(info_by_type) = info.get(&Type::Video) { - values.extend(map! { + map! { @extend values "icon_video" => Value::icon("xrandr"), "info_video" => Value::text(format!("{}", info_by_type)) - }); + } } if let Some(info_by_type) = info.get(&Type::Webcam) { - values.extend(map! { + map! { @extend values "icon_webcam" => Value::icon("webcam"), "info_webcam" => Value::text(format!("{}", info_by_type)) - }); + } } if let Some(info_by_type) = info.get(&Type::Unknown) { - values.extend(map! { + map! { @extend values "icon_unknown" => Value::icon("unknown"), "info_unknown" => Value::text(format!("{}", info_by_type)) - }); + } } widget.set_values(values); diff --git a/src/blocks/weather.rs b/src/blocks/weather.rs index 9636bc308..cb413d529 100644 --- a/src/blocks/weather.rs +++ b/src/blocks/weather.rs @@ -264,8 +264,8 @@ impl WeatherResult { if let Some(forecast) = self.forecast { macro_rules! map_forecasts { ({$($suffix: literal => $src: expr),* $(,)?}) => { - values.extend(map!{ - $( + map!{ @extend values + $( concat!("temp_f", $suffix) => Value::degrees($src.temp), concat!("apparent_f", $suffix) => Value::degrees($src.apparent), concat!("humidity_f", $suffix) => Value::percents($src.humidity), @@ -273,7 +273,7 @@ impl WeatherResult { concat!("wind_kmh_f", $suffix) => Value::number($src.wind_kmh), concat!("direction_f", $suffix) => Value::text(convert_wind_direction($src.wind_direction).into()), )* - }); + } }; } map_forecasts!({ @@ -283,12 +283,11 @@ impl WeatherResult { "fin" => forecast.fin, }); - values.extend(map! { - "icon_ffin" => Value::icon(forecast.fin.icon.to_icon_str()), - "weather_ffin" => Value::text(forecast.fin.weather.clone()), - "weather_verbose_ffin" => Value::text(forecast.fin.weather_verbose.clone()), - - }); + map! { @extend values + "icon_ffin" => Value::icon(forecast.fin.icon.to_icon_str()), + "weather_ffin" => Value::text(forecast.fin.weather.clone()), + "weather_verbose_ffin" => Value::text(forecast.fin.weather_verbose.clone()), + } } values } diff --git a/src/util.rs b/src/util.rs index 30e780528..d110e3bdb 100644 --- a/src/util.rs +++ b/src/util.rs @@ -138,29 +138,27 @@ pub async fn has_command(command: &str) -> Result { /// /// ```ignore /// let opt = Some(1); -/// let map: HashMap<&'static str, String> = map! { +/// let m: HashMap<&'static str, String> = map! { /// "key" => "value", /// [if true] "hello" => "world", /// [if let Some(x) = opt] "opt" => x.to_string(), /// }; +/// map! { @extend m +/// "new key" => "new value", +/// "one" => "more", +/// } /// ``` #[macro_export] macro_rules! map { - ($( $([$($cond_tokens:tt)*])? $key:literal => $value:expr ),* $(,)?) => {{ - #[allow(unused_mut)] - let mut m = ::std::collections::HashMap::new(); + (@extend $map:ident $( $([$($cond_tokens:tt)*])? $key:literal => $value:expr ),* $(,)?) => {{ $( - map!(@insert m, $key, $value $(,$($cond_tokens)*)?); + map!(@insert $map, $key, $value $(,$($cond_tokens)*)?); )* - m }}; - ($( $key:expr => $value:expr ),* $(,)?) => {{ - #[allow(unused_mut)] - let mut m = ::std::collections::HashMap::new(); + (@extend $map:ident $( $key:expr => $value:expr ),* $(,)?) => {{ $( - map!(@insert m, $key, $value); + map!(@insert $map, $key, $value); )* - m }}; (@insert $map:ident, $key:expr, $value:expr) => {{ $map.insert($key.into(), $value.into()); @@ -175,6 +173,12 @@ macro_rules! map { $map.insert($key.into(), $value.into()); } }}; + ($($tt:tt)*) => {{ + #[allow(unused_mut)] + let mut m = ::std::collections::HashMap::new(); + map!(@extend m $($tt)*); + m + }}; } pub use map;