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.
62 lines
2.9 KiB
Rust
62 lines
2.9 KiB
Rust
//! Embedding convention for the static reference data files (`data/*.yml`)
|
|
//!
|
|
//! Reference data that changes independently of the code — distro series
|
|
//! pointers, pinned SSH host keys, package quirks — lives in YAML files
|
|
//! under `data/` at the repo root instead of hardcoded in the source, so
|
|
//! it is updatable in one reviewable place.
|
|
//!
|
|
//! This module is deliberately not a central registry: each file is
|
|
//! embedded by the module that owns it (distro_info.rs owns
|
|
//! data/distro_info.yml, launchpad.rs owns data/launchpad.yml,
|
|
//! apt/keyring.rs owns data/keyserver.yml, new/origin.rs owns
|
|
//! data/forges.yml, put/ssh.rs owns data/host_keys.yml, quirks.rs owns
|
|
//! 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 [`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.
|
|
//!
|
|
//! Paths and URLs in the data files carry their variable parts as `{name}`
|
|
//! placeholders, substituted with `str::replace` at the use site — no
|
|
//! template engine.
|
|
|
|
/// Embed one YAML data file as a lazily-parsed static, following the
|
|
/// convention documented at the module level.
|
|
///
|
|
/// Takes the visibility of the generated static (none for private, `pub` or
|
|
/// `pub(crate)`-style), its name, its struct type (which stays defined in
|
|
/// the owning module, next to its accessors) and the file path relative to
|
|
/// 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!` →
|
|
/// 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! {
|
|
/// static ref MY_DATA: MyData = "../data/my_data.yml"
|
|
/// }
|
|
/// ```
|
|
macro_rules! embed_data {
|
|
($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"
|
|
))
|
|
});
|
|
};
|
|
}
|
|
|
|
/// Makes the macro available through the module path
|
|
/// (`use crate::data::embed_data;`)
|
|
pub(crate) use embed_data;
|