oncelock 0.1.0-alpha.0

A fast and simple implementation of OnceLock
Documentation
macro_rules! cfg_version {
    ($($item:tt)*) => ({
        #[rustversion::$($item)*]
        const RES: bool = true;
        #[rustversion::not($($item)*)]
        const RES: bool = false;
        RES
    });
}

fn has_feature(name: &str) -> bool {
    let name = name.replace('-', "_").to_uppercase();
    std::env::var_os(format!("CARGO_FEATURE_{}", name)).is_some()
}

fn join<T: IntoIterator<Item = String>>(sep: &str, values: T) -> String {
    let mut values = values.into_iter();
    let mut buffer = String::new();
    if let Some(first) = values.next() {
        buffer.push_str(&first);
        for remaining in values {
            buffer.push_str(sep);
            buffer.push_str(&remaining);
        }
    }
    buffer
}
fn emit_check_cfg(name: &str, values: Option<&[&str]>) {
    let values = match values {
        None => "none()".into(),
        Some(items) => join(",", items.iter().map(&|x| format!("\"{}\"", x))),
    };
    println!("cargo:rustc-check-cfg=cfg({}, values({}))", name, values);
}
fn emit_cfg(name: &str, value: Option<&str>) {
    let value = match value {
        Some(value) => format!("=\"{}\"", value),
        None => String::new(),
    };
    println!("cargo:rustc-cfg={}{}", name, value);
}
const PARKING_LOT_VERSIONS: &[&str] = &["v0_12"];
// ordered by priority (highest to lowest)
const SPIN_VERSIONS: &[&str] = &["v0_10", "v0_9"];

fn find_dep_version<'a>(dep: &str, versions: &[&'a str]) -> Option<&'a str> {
    versions
        .iter()
        .find(|&&v| has_feature(&format!("{}_{}", dep, v)))
        .cloned()
}

pub fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    if cfg_version!(since(1.80)) {
        emit_check_cfg("sync_backend", Some(&["parking_lot", "std", "spin"]));
        emit_check_cfg("parking_lot_version", Some(PARKING_LOT_VERSIONS));
        emit_check_cfg("spin_version", Some(SPIN_VERSIONS));
        // misc flags
        emit_check_cfg("missing_sync_backend", None);
        // version flags
        emit_check_cfg("has_maybe_uninit", None);
        emit_check_cfg("has_compile_error", None);
        emit_check_cfg("has_once_is_completed", None);
        emit_check_cfg("has_track_caller", None);
    }
    if cfg_version!(since(1.36)) {
        emit_cfg("has_maybe_uninit", None);
    }
    if cfg_version!(since(1.38)) {
        emit_cfg("has_compile_error", None);
    }
    if cfg_version!(since(1.43)) {
        emit_cfg("has_once_is_completed", None);
    }
    if cfg_version!(since(1.46)) {
        emit_cfg("has_track_caller", None);
    }
    if let Some(version) = find_dep_version("parking_lot", PARKING_LOT_VERSIONS) {
        emit_cfg("parking_lot_version", Some(version));
        emit_cfg("sync_backend", Some("parking_lot"));
    } else if has_feature("std") {
        emit_cfg("sync_backend", Some("std"));
    } else if let Some(version) = find_dep_version("spin", SPIN_VERSIONS) {
        emit_cfg("spin_version", Some(version));
        emit_cfg("sync_backend", Some("spin"));
    } else {
        emit_cfg("missing_sync_backend", None);
    }
}