diff options
Diffstat (limited to 'crates/mozart-registry/src/repository/packagist_repo.rs')
| -rw-r--r-- | crates/mozart-registry/src/repository/packagist_repo.rs | 121 |
1 files changed, 0 insertions, 121 deletions
diff --git a/crates/mozart-registry/src/repository/packagist_repo.rs b/crates/mozart-registry/src/repository/packagist_repo.rs deleted file mode 100644 index fa656b7..0000000 --- a/crates/mozart-registry/src/repository/packagist_repo.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! [`Repository`] backed by the live Packagist HTTP API. -//! -//! Wraps the existing [`crate::packagist::fetch_package_versions`] so the -//! resolver sees the same data either through this trait or via the legacy -//! direct call. Construction takes ownership of the [`Cache`] handle so -//! callers no longer thread it through `ResolveRequest` / `LockFileGenerationRequest`. - -use super::{LoadResult, NamedPackagistVersion, PackageQuery, Repository, SearchMode}; -use crate::cache::Cache; -use crate::packagist; -use crate::packagist::SearchResult; - -pub struct PackagistRepository { - id: String, - cache: Cache, -} - -impl PackagistRepository { - pub fn new(cache: Cache) -> Self { - Self { - id: "packagist.org".to_string(), - cache, - } - } -} - -#[async_trait::async_trait] -impl Repository for PackagistRepository { - fn id(&self) -> &str { - &self.id - } - - async fn load_packages(&self, queries: &[PackageQuery<'_>]) -> anyhow::Result<LoadResult> { - let mut result = LoadResult::default(); - for query in queries { - // Errors propagate to the caller. Composer's - // `ComposerRepository::loadAsyncPackages` distinguishes 404 - // (empty result, no error) from transport failures (exception); - // Mozart's underlying `fetch_package_versions` doesn't yet make - // that distinction, so for now both surface as `Err` and the - // caller decides whether the loop wants to continue (transitive - // exploration) or abort (seed-time fetch failure). - let versions = packagist::fetch_package_versions(query.name, &self.cache).await?; - // A successful fetch counts as "this repo authoritatively knows - // the name", even if the version list is empty — mirrors - // Composer's `ArrayRepository::loadPackages` which adds the - // name to `namesFound` regardless of constraint match. - result.names_found.push(query.name.to_string()); - for version in versions { - result.packages.push(NamedPackagistVersion { - name: query.name.to_string(), - version, - }); - } - } - Ok(result) - } - - async fn search( - &self, - query: &str, - mode: SearchMode, - package_type: Option<&str>, - ) -> anyhow::Result<Vec<SearchResult>> { - match mode { - SearchMode::Fulltext => { - let (results, _total) = packagist::search_packages(query, package_type).await?; - Ok(results) - } - SearchMode::Name => { - let pattern = build_name_regex(query)?; - let names = packagist::fetch_package_names(package_type, &self.cache).await?; - Ok(names - .into_iter() - .filter(|name| pattern.is_match(name)) - .map(empty_search_result) - .collect()) - } - SearchMode::Vendor => { - let pattern = build_name_regex(query)?; - let vendors = packagist::fetch_vendor_names(&self.cache).await?; - Ok(vendors - .into_iter() - .filter(|name| pattern.is_match(name)) - .map(empty_search_result) - .collect()) - } - } - } -} - -/// Build the case-insensitive `(?:t1|t2|...)` regex from whitespace-split -/// tokens, mirroring Composer's `'{(?:'.implode('|', $matches).')}i'`. -/// -/// Tokens are joined as-is — callers are expected to have already escaped -/// regex metacharacters (`SearchCommand` calls `preg_quote`; Mozart calls -/// `regex::escape` before reaching this point). -fn build_name_regex(query: &str) -> anyhow::Result<regex::Regex> { - let tokens: Vec<&str> = query.split_whitespace().collect(); - let body = if tokens.is_empty() { - String::new() - } else { - tokens.join("|") - }; - Ok(regex::Regex::new(&format!("(?i)(?:{body})"))?) -} - -/// Build a [`SearchResult`] with only `name` populated, mirroring the shape -/// Composer returns for `SEARCH_NAME` / `SEARCH_VENDOR` modes -/// (`['name' => $name]`, all other fields `null`). -fn empty_search_result(name: String) -> SearchResult { - SearchResult { - name, - description: String::new(), - url: String::new(), - repository: None, - downloads: 0, - favers: 0, - abandoned: None, - } -} |
