mercur 0.1.4

mercur - junolang package manager
use xxhash_rust::xxh3::xxh3_64;

/// Computes the runtime ID used by Mercur.
///
/// This ID is stored inside the registry and used for
/// fast lookups.
///
/// NOTE:
/// XXH3 is NOT used for security.
/// It is only used as a fast lookup key.
#[inline]
pub fn runtime_id(s: &str) -> u64 {
    xxh3_64(s.as_bytes())
}

/// Hash of an authority.
///
/// Example:
///
/// "mercur"
/// "core"
#[inline]
pub fn authority_id(authority: &str) -> u64 {
    runtime_id(authority)
}

/// Hash of a package.
///
/// Example:
///
/// "http"
/// "serde"
#[inline]
pub fn package_id(package: &str) -> u64 {
    runtime_id(package)
}

/// Hash of a namespace.

#[inline]
pub fn namespace_id(namespace: &str) -> u64 {
    runtime_id(&normalize_namespace(namespace))
}

/// Converts
///
/// //////foo///bar///
///
/// into
///
/// /foo/bar
pub fn normalize_namespace(namespace: &str) -> String {
    if namespace.is_empty() {
        return "/".to_string();
    }

    let mut out = String::with_capacity(namespace.len());

    out.push('/');

    let mut first = true;

    for part in namespace.split('/') {
        if part.is_empty() {
            continue;
        }

        if !first {
            out.push('/');
        }

        out.push_str(part);

        first = false;
    }

    out
}

use crate::registry::schema::registry::Hash;

/// Parses a SHA-256 hex string into the FlatBuffers Hash struct.
///
/// Input:
///
/// 5514287c8e82766136b3239df81be8e0...
///
/// Output:
///
/// Hash {
///     a,
///     b,
///     c,
///     d,
/// }
pub fn parse_hash(hash: &str) -> Hash {
    let mut parts = [0u64; 4];

    for (i, chunk) in hash.trim().as_bytes().chunks(16).take(4).enumerate() {
        let s = std::str::from_utf8(chunk).unwrap_or("0");

        parts[i] = u64::from_str_radix(s, 16).unwrap_or(0);
    }

    Hash::new(parts[0], parts[1], parts[2], parts[3])
}