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;
}