From 3adfd334df6f4116f1a043d97e9bb33b636edf86 Mon Sep 17 00:00:00 2001 From: Chris <89366859+ChristopherPerry6060@users.noreply.github.com> Date: Thu, 2 Nov 2023 16:29:50 -0400 Subject: [PATCH] fix: `leptos_router::params_map!` (#1973) Fixing implementation comes with the benefit of knocking a crate out of the deps tree (`common_macros`). --- router/Cargo.toml | 1 - router/src/history/params.rs | 34 ++++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/router/Cargo.toml b/router/Cargo.toml index 8c90791a5..e87137818 100644 --- a/router/Cargo.toml +++ b/router/Cargo.toml @@ -14,7 +14,6 @@ leptos_integration_utils = { workspace = true, optional = true } leptos_meta = { workspace = true, optional = true } cached = { version = "0.45.0", optional = true } cfg-if = "1" -common_macros = "0.1" gloo-net = { version = "0.2", features = ["http"] } lazy_static = "1" linear-map = { version = "1", features = ["serde_impl"] } diff --git a/router/src/history/params.rs b/router/src/history/params.rs index 20ee1df3d..9e0115c96 100644 --- a/router/src/history/params.rs +++ b/router/src/history/params.rs @@ -72,31 +72,41 @@ impl Default for ParamsMap { } } -/// A declarative way of creating a [`ParamsMap`]. +/// Create a [`ParamsMap`] in a declarative style. /// /// ``` /// # use leptos_router::params_map; /// let map = params_map! { -/// "id" => "1" +/// "crate" => "leptos", +/// 42 => true, // where key & val: std::fmt::Display /// }; -/// assert_eq!(map.get("id"), Some(&"1".to_string())); -/// assert_eq!(map.get("missing"), None) +/// assert_eq!(map.get("crate"), Some(&"leptos".to_string())); +/// assert_eq!(map.get("42"), Some(&true.to_string())) /// ``` +// Original implementation included the below credits. +// // Adapted from hash_map! in common_macros crate // Copyright (c) 2019 Philipp Korber // https://github.com/rustonaut/common_macros/blob/master/src/lib.rs #[macro_export] macro_rules! params_map { - ($($key:expr => $val:expr),* ,) => ( - $crate::ParamsMap!($($key => $val),*) - ); - ($($key:expr => $val:expr),*) => ({ - let start_capacity = common_macros::const_expr_count!($($key);*); + // Fast path avoids allocation. + () => { $crate::ParamsMap::with_capacity(0) }; + + // Counting repitions by n = 0 ( + 1 )* + // + // https://github.com/rust-lang/rust/issues/83527 + // When stabilized you can use "metavaribale exprs" instead + // + // `$key | $val` must be included in the repetition to be valid, it is + // stringified to null out any possible side-effects. + ($($key:expr => $val:expr),* $(,)?) => {{ + let n = 0 $(+ { _ = stringify!($key); 1 })*; #[allow(unused_mut)] - let mut map = linear_map::LinearMap::with_capacity(start_capacity); + let mut map = $crate::ParamsMap::with_capacity(n); $( map.insert($key.to_string(), $val.to_string()); )* - $crate::ParamsMap(map) - }); + map + }}; } /// A simple method of deserializing key-value data (like route params or URL search)