From 239bcb28dfc32b481240dd2f0b64f1abc80cb00a Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Sat, 3 Oct 2026 01:28:00 +0200 Subject: [PATCH] data,apt/release,distro_info,new: replace lazy_static with LazyLock Unify the lazily-initialized statics on std::sync::LazyLock, which the newer code already uses: the embed_data! macro expands to a plain static now, which also removes the visibility-forwarding workaround the lazy_static! matcher forced on it (the @expand arm wrapping vis in parentheses), and the 'static ref' spelling is kept at the call sites. distro_info's HTTP client, the apt keyring cache and the new-template registry follow the same pattern. --- src/apt/release.rs | 11 +++++------ src/data.rs | 37 +++++++++++++------------------------ src/distro_info.rs | 20 ++++++++++---------- src/new/templates/mod.rs | 17 ++++++++--------- 4 files changed, 36 insertions(+), 49 deletions(-) diff --git a/src/apt/release.rs b/src/apt/release.rs index 412c695..0a98702 100644 --- a/src/apt/release.rs +++ b/src/apt/release.rs @@ -45,7 +45,6 @@ //! keyserver responses are armored) are dearmored in-process, so no `gpg` //! binary is needed. -use lazy_static::lazy_static; use log::{debug, warn}; use serde::Deserialize; use std::collections::HashMap; @@ -53,6 +52,7 @@ use std::error::Error; use std::fmt; use std::path::Path; use std::path::PathBuf; +use std::sync::LazyLock; use std::sync::Mutex; use std::sync::PoisonError; @@ -793,11 +793,10 @@ async fn fetch_optional(url: &str) -> Option> { None } -lazy_static! { - /// Downloaded keyrings, keyed by URL: keyrings are small but would - /// otherwise be re-downloaded once per series/pocket lookup - static ref KEYRING_CACHE: Mutex>> = Mutex::new(HashMap::new()); -} +/// Downloaded keyrings, keyed by URL: keyrings are small but would +/// otherwise be re-downloaded once per series/pocket lookup +static KEYRING_CACHE: LazyLock>>> = + LazyLock::new(|| Mutex::new(HashMap::new())); /// Read the keyring cache, ignoring poisoning (the map is only corrupted on /// panics, in which case a fresh map is just as good) diff --git a/src/data.rs b/src/data.rs index e750ec7..970b66c 100644 --- a/src/data.rs +++ b/src/data.rs @@ -13,7 +13,7 @@ //! data/quirks.yml) through the [`embed_data!`] macro below, so data //! and its accessors stay together and a diff touching one domain cannot //! half-touch another. The macro embeds the file at compile time and -//! parses it once into a `lazy_static` on first use; since the data ships +//! parses it once into a [`LazyLock`] on first use; since the data ships //! inside the binary, a parse failure is a build-time bug that cannot be //! recovered from at runtime, and the macro panics on it. //! @@ -30,8 +30,9 @@ /// the invoking source file (`"../data/distro_info.yml"` from /// `src/distro_info.rs`, `"../../data/host_keys.yml"` from /// `src/put/ssh.rs`, ...), and expands to the house `include_str!` → -/// `lazy_static` → parse pattern — only the embed+parse boilerplate is -/// generated. +/// parse-on-first-use pattern — only the embed+parse boilerplate is +/// generated. The `static ref` spelling is kept from the macro's +/// `lazy_static!` ancestry; it expands to a plain `LazyLock` static. /// /// ```ignore /// embed_data! { @@ -39,31 +40,19 @@ /// } /// ``` macro_rules! embed_data { - // Internal arm: the visibility arrives wrapped in parentheses (empty for - // private statics) because `lazy_static!` only re-matches literal - // `pub`/`pub(...)` token sequences, not an opaque forwarded `vis`. - (@expand ($($vis:tt)*) static ref $name:ident : $ty:ty = $path:literal) => { - lazy_static::lazy_static! { - // The YAML is include_str!'d at compile time and statically - // valid; if it ever failed to parse it would be a build-time bug - // that cannot be recovered from at runtime, so panicking here is - // acceptable. - $($vis)* static ref $name: $ty = serde_yaml::from_str(include_str!($path)) + ($vis:vis static ref $name:ident : $ty:ty = $path:literal) => { + // The YAML is include_str!'d at compile time and statically + // valid; if it ever failed to parse it would be a build-time bug + // that cannot be recovered from at runtime, so panicking here is + // acceptable. + $vis static $name: ::std::sync::LazyLock<$ty> = ::std::sync::LazyLock::new(|| { + serde_yaml::from_str(include_str!($path)) .expect(concat!( "built-in ", $path, " data is statically valid and must parse" - )); - } - }; - (static ref $name:ident : $ty:ty = $path:literal) => { - $crate::data::embed_data!(@expand () static ref $name : $ty = $path); - }; - (pub static ref $name:ident : $ty:ty = $path:literal) => { - $crate::data::embed_data!(@expand (pub) static ref $name : $ty = $path); - }; - (pub ($($vis:tt)+) static ref $name:ident : $ty:ty = $path:literal) => { - $crate::data::embed_data!(@expand (pub ($($vis)+)) static ref $name : $ty = $path); + )) + }); }; } diff --git a/src/distro_info.rs b/src/distro_info.rs index 9e7fb6c..45505af 100644 --- a/src/distro_info.rs +++ b/src/distro_info.rs @@ -1,10 +1,10 @@ use crate::data::embed_data; use chrono::NaiveDate; -use lazy_static::lazy_static; use serde::Deserialize; use std::collections::HashMap; use std::error::Error; use std::path::Path; +use std::sync::LazyLock; use std::time::Duration; #[derive(Debug, Clone)] @@ -104,20 +104,20 @@ embed_data! { static ref DATA: Data = "../data/distro_info.yml" } -lazy_static! { - // Shared HTTP client used for all outgoing plain requests: timeouts keep - // a hanging remote (connect or transfer) from stalling pkh indefinitely. - // The short pool idle timeout and TCP keepalive avoid reusing keep-alive - // connections that the remote closed in the meantime, which surfaces as - // spurious 'error sending request' failures on busy mirrors/CDNs. - static ref HTTP_CLIENT: reqwest::Client = reqwest::Client::builder() +// Shared HTTP client used for all outgoing plain requests: timeouts keep +// a hanging remote (connect or transfer) from stalling pkh indefinitely. +// The short pool idle timeout and TCP keepalive avoid reusing keep-alive +// connections that the remote closed in the meantime, which surfaces as +// spurious 'error sending request' failures on busy mirrors/CDNs. +static HTTP_CLIENT: LazyLock = LazyLock::new(|| { + reqwest::Client::builder() .connect_timeout(Duration::from_secs(10)) .timeout(Duration::from_secs(30)) .pool_idle_timeout(Duration::from_secs(10)) .tcp_keepalive(Duration::from_secs(30)) .build() - .expect("building the shared HTTP client with static options cannot fail"); -} + .expect("building the shared HTTP client with static options cannot fail") +}); /// Shared HTTP client with a connect timeout (10s) and a total request /// timeout (30s), to be used for all outgoing plain HTTP(S) requests diff --git a/src/new/templates/mod.rs b/src/new/templates/mod.rs index 9e2bdde..9576183 100644 --- a/src/new/templates/mod.rs +++ b/src/new/templates/mod.rs @@ -52,6 +52,7 @@ pub mod rust; pub mod shell; use std::path::{Path, PathBuf}; +use std::sync::LazyLock; use serde::Deserialize; @@ -478,15 +479,13 @@ static TEMPLATE_SOURCES: &[TemplateSources] = &[ }, ]; -lazy_static::lazy_static! { - /// The parsed registry: manifest data plus resolved hooks, in the - /// order of [`TEMPLATE_SOURCES`] (wizard menu = detection priority). - static ref REGISTRY: Vec