mercur 0.1.2

mercur - junolang package manager
use flatbuffers::Vector;

use crate::registry::{
    schema::registry::PkgRegistryEntry,
    search::{SearchEngine},
};

impl SearchEngine {
    pub async fn search_in_registry<'a>(
        &'a mut self,
        registry_ref: &str,
        package: String,
        namespaces: Vec<&str>,
        authority: Option<String>,
        version: Option<String>,
        hash: Option<String>,

        out: &mut Vec<PkgRegistryEntry<'a>>,
    ) {
        let registry = self.load_registry(registry_ref.to_owned());
        if namespaces.is_empty() {
            let pkgs = &mut registry
                .packages()
                .unwrap_or(Vector::default())
                .iter()
                .filter(|x: &PkgRegistryEntry| {
                    match_pkg(
                        x,
                        package.clone(),
                        namespaces.clone(),
                        authority.clone(),
                        version.clone(),
                        hash.clone(),
                    )
                })
                .collect::<Vec<PkgRegistryEntry>>();
            out.append(pkgs);
        }
    }
}

fn match_pkg(
    x: &PkgRegistryEntry<'_>,
    package: String,
    namespaces: Vec<&str>,
    authority: Option<String>,
    version: Option<String>,
    pkg_hash: Option<String>,
) -> bool {
    if x.name() != package {
        return false;
    }
    if authority.is_some() {
        if authority.unwrap() != x.authority() {
            return false;
        }
    }
    if version.is_some() {
        let version = version.unwrap();
        let mut success = false;
        let mut hash: [u64; 4] = [0, 0, 0, 0];
        for v in x.versions() {
            if format!(
                "{}.{}.{}-{}",
                v.major(),
                v.minor(),
                v.patch(),
                v.tag().unwrap_or("")
            ) == version
                || format!("{}.{}.{}", v.major(), v.minor(), v.patch()) == version
            {
                success = true;
                break;
            }
        }
        if !success {
            return false;
        }
        if pkg_hash.is_some() {
            let pkg_hash = pkg_hash.unwrap();
            let pkg_hash = pkg_hash.trim();

            let mut parts = [0u64; 4];

            for (i, chunk) in pkg_hash.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);
            }
            if parts != hash {
                return false
            }
        }
    }

    return true;
}