splicer 2.4.1

Plan and generate middleware splice operations for WebAssembly component composition graphs.
Documentation
//! Catalogue of middleware components shipped with splicer.
//!
//! Tier-1/2 builtins are pre-built wasm components fetched from OCI
//! (see [`tier1_2`]). Tier-3/4 strategy compilation (for both shipped
//! builtins and user-supplied crates) lives in [`crate::strategies`].
//! The public API ([`known_names`], [`list_with_manifests`],
//! [`resolve_manifest`]) unifies tier-1/2 and tier-3/4 builtins —
//! callers don't think about distribution mechanics.

use anyhow::Result;
use std::path::{Path, PathBuf};

/// User cache directory: `$XDG_CACHE_HOME` or `~/.cache` on Unix,
/// `%LOCALAPPDATA%` on Windows.
pub(crate) fn user_cache_dir() -> Option<PathBuf> {
    if cfg!(target_os = "windows") {
        std::env::var_os("LOCALAPPDATA").map(PathBuf::from)
    } else {
        std::env::var_os("XDG_CACHE_HOME")
            .map(PathBuf::from)
            .or_else(|| std::env::var_os("HOME").map(|h| Path::new(&h).join(".cache")))
    }
}

mod tier1_2;

pub use tier1_2::materialize_into;

pub(crate) use tier1_2::load_resolved_bytes;

#[cfg(test)]
pub(crate) use tier1_2::with_fake_builtins;

/// Names of every user-facing builtin shipped with this splicer
/// build, sorted. Spans both tier-1/2 (OCI-distributed wasm) and
/// tier-3/4 (embedded source crates — see [`crate::strategies`]).
pub fn known_names() -> Vec<&'static str> {
    let mut all: Vec<&'static str> = tier1_2::known_names();
    all.extend(crate::strategies::names());
    all.sort();
    all.dedup();
    all
}

/// Resolve every user-facing builtin's manifest and return the pairs
/// in [`known_names`] order. Manifests are `Option` because some
/// tier-1/2 builtins predate the manifest substrate.
///
/// Resolution errors land as `Err(...)` rather than panicking so the
/// caller can render partial output — `splicer builtin` shouldn't
/// crash when one OCI pull misbehaves.
pub fn list_with_manifests() -> Vec<(&'static str, Result<Option<builtin_protocol::Manifest>>)> {
    let mut out = Vec::new();
    for name in known_names() {
        let entry = if crate::strategies::is_embedded_builtin(name) {
            crate::strategies::read_manifest(name).map(Some)
        } else {
            tier1_2::manifest_for(name)
        };
        out.push((name, entry));
    }
    out
}

/// Resolve a single builtin's manifest. For tier-3/4 the manifest is
/// always present (every shipped strategy ships one); for tier-1/2 a
/// missing manifest is an error.
pub fn resolve_manifest(name: &str) -> Result<builtin_protocol::Manifest> {
    if crate::strategies::is_embedded_builtin(name) {
        crate::strategies::read_manifest(name)
    } else {
        tier1_2::resolve_manifest(name)
    }
}