afia-component-sys 0.0.4

A low-level Rust wrapper for `libafia_component`.
Documentation
use std::env;
use std::path::Path;

#[cfg(unix)]
const LIB_FILENAME: &str = "libafia_component.a";
#[cfg(windows)]
const LIB_FILENAME: &str = "afia_component.lib";

fn main() {
    link_libafia_component();
}

/// First, check for a `LIB_AFIA_COMPONENT_DIR` environment variable.
///
/// On Unix, the path should point to a directory that contains a `libafia_component.a` native
/// library.
/// On Windows, the directory should contain an `afia_component.lib`.
///
/// If no `LIB_AFIA_COMPONENT_DIR` environment variable is present, we check `/usr/local/lib/afia`.
///
/// A `libafia_component` library can be downloaded from https://afiaproject.com .
fn link_libafia_component() {
    if let Some(libafia_component_dir) = env::var("LIB_AFIA_COMPONENT_DIR").ok() {
        // `/path/to/lib/linux-x86_64`
        let lib_os_arch_dir = Path::new(&libafia_component_dir).join(lib_subdir());
        link_libafia_component_at_dir(&lib_os_arch_dir)
    } else {
        print_rustc_link_search_dir(&Path::new("/usr/local/lib/afia").join(lib_subdir()));
    }

    println!("cargo:rustc-link-lib=static=afia_component");
}

fn link_libafia_component_at_dir(libafia_component_dir: &Path) {
    assert_dir_contains_native_lib(&libafia_component_dir);
    print_rustc_link_search_dir(&libafia_component_dir);
}

fn assert_dir_contains_native_lib(libafia_component_dir: &Path) {
    let is_missing_lib = !libafia_component_dir.join(LIB_FILENAME).exists();

    if is_missing_lib {
        let dir_display = libafia_component_dir.display();
        panic!(r#"File not found: {dir_display}/{LIB_FILENAME}"#);
    }
}

fn print_rustc_link_search_dir(dir: &Path) {
    println!("cargo:rustc-link-search=native={}", dir.to_str().unwrap());
}

/// Get the subdirectory within the `lib` dir, such as `lib/linux-x86_64` or `lib/macos-aarch64-test`.
fn lib_subdir() -> String {
    let os_and_arch = match env::var("TARGET").unwrap().as_str() {
        "x86_64-unknown-linux-gnu" => "linux-x86_64",
        "x86_64-apple-darwin" => "macos-x86_64",
        "aarch64-apple-darwin" => "macos-aarch64",
        "x86_64-pc-windows-msvc" => "windows-x86_64",
        "wasm32-unknown-unknown" => "wasm32",
        _ => unimplemented!(),
    };

    let is_test_utils_enabled = env::var("CARGO_FEATURE_TEST_UTILS").is_ok();
    let maybe_test = if is_test_utils_enabled { "-test" } else { "" };
    format!("{os_and_arch}{maybe_test}")
}