diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-23 03:07:15 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-23 15:48:00 +0900 |
| commit | e068a9d644fde6659a88accd55b3f1d0d9d7cf46 (patch) | |
| tree | bb719a70eb8c840957a94a5601df8961055ceb0f /crates/shirabe/src/repository | |
| parent | 60eb89529c8af2e4477e0bb65ed9e0f2dc7d3dd7 (diff) | |
| download | php-shirabe-e068a9d644fde6659a88accd55b3f1d0d9d7cf46.tar.gz php-shirabe-e068a9d644fde6659a88accd55b3f1d0d9d7cf46.tar.zst php-shirabe-e068a9d644fde6659a88accd55b3f1d0d9d7cf46.zip | |
refactor(promise): rewrite promise bodies to async/await
Mechanically convert promise-returning function bodies to async/await:
resolve() returns the value directly, forwarding calls get .await, and
simple .then chains become await sequences. Also collapse the installer
double-Option (Result<Option<Option<PhpMixed>>> -> Result<Option<PhpMixed>>).
Hard spots that depend on the Loop::wait / job-machine boundary
(accept/reject orchestration, closures capturing &mut self, batch waits)
are left intact and marked with TODO(phase-c-promise) for manual porting.
The crate does not compile yet; traits still need #[async_trait].
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/repository')
| -rw-r--r-- | crates/shirabe/src/repository/composer_repository.rs | 105 |
1 files changed, 47 insertions, 58 deletions
diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 7601117..3c5eb31 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -1103,6 +1103,9 @@ impl ComposerRepository { .map_or(false, |c| c.metadata) && (allow_partial_advisories || api_url.is_none()) { + // TODO(phase-c-promise): collects start_cached_async_download().then_boxed() promises and + // drives them via Loop::wait; rewrite to await the collected futures once the async Loop + // boundary lands. let mut promises: Vec<Box<dyn PromiseInterface>> = Vec::new(); let names: Vec<String> = package_constraint_map.keys().cloned().collect(); for name in names { @@ -1848,6 +1851,9 @@ impl ComposerRepository { let mut packages: IndexMap<String, Box<dyn BasePackage>> = IndexMap::new(); let mut names_found: IndexMap<String, bool> = IndexMap::new(); + // TODO(phase-c-promise): collects start_cached_async_download().then_boxed() promises and + // drives them via Loop::wait; rewrite to await the collected futures once the async Loop + // boundary lands. let mut promises: Vec<Box<dyn PromiseInterface>> = Vec::new(); if self.lazy_providers_url.is_none() { @@ -2131,62 +2137,43 @@ impl ComposerRepository { contents_opt = None; } - let promise = self.async_fetch_file(&url, &cache_key, last_modified.as_deref())?; - let url_owned = url.clone(); - let cache_key_owned = cache_key.clone(); - let contents = contents_opt; - // TODO(phase-b): then_boxed expects closure returning Box<dyn PromiseInterface>, - // not anyhow::Result<PhpMixed>; needs structural reshape - Ok(promise.then_boxed( - Some(Box::new( - move |response: PhpMixed| -> Box<dyn PromiseInterface> { - let _result: anyhow::Result<PhpMixed> = (|| -> anyhow::Result<PhpMixed> { - let mut packages_source = - format!("downloaded file ({})", Url::sanitize(url_owned.clone())); + // PHP: return $this->asyncFetchFile(...)->then(function ($response) use (...): array { ... }); + let response = self + .async_fetch_file(&url, &cache_key, last_modified.as_deref()) + .await?; - let response_data = if response.as_bool() == Some(true) { - packages_source = format!( - "cached file ({} originating from {})", - cache_key_owned, - Url::sanitize(url_owned.clone()) - ); - contents - .clone() - .map(|m| { - PhpMixed::Array( - m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(), - ) - }) - .unwrap_or(PhpMixed::Null) - } else { - response - }; + let mut packages_source = format!("downloaded file ({})", Url::sanitize(url.clone())); - let response_arr = response_data.as_array(); - let has_pkg = response_arr - .and_then(|a| a.get("packages")) - .and_then(|v| v.as_array()) - .map_or(false, |a| a.contains_key(&package_name)); - let has_advisories = - response_arr.map_or(false, |a| a.contains_key("security-advisories")); - if !has_pkg && !has_advisories { - return Ok(PhpMixed::List(vec![ - Box::new(PhpMixed::Null), - Box::new(PhpMixed::String(packages_source)), - ])); - } + let response_data = if response.as_bool() == Some(true) { + packages_source = format!( + "cached file ({} originating from {})", + cache_key, + Url::sanitize(url.clone()) + ); + contents_opt + .map(|m| PhpMixed::Array(m.into_iter().map(|(k, v)| (k, Box::new(v))).collect())) + .unwrap_or(PhpMixed::Null) + } else { + response + }; - Ok(PhpMixed::List(vec![ - Box::new(response_data), - Box::new(PhpMixed::String(packages_source)), - ])) - })(); - // TODO(phase-b): return a real PromiseInterface - todo!("return real PromiseInterface") - }, - )), - None, - )) + let response_arr = response_data.as_array(); + let has_pkg = response_arr + .and_then(|a| a.get("packages")) + .and_then(|v| v.as_array()) + .map_or(false, |a| a.contains_key(&package_name)); + let has_advisories = response_arr.map_or(false, |a| a.contains_key("security-advisories")); + if !has_pkg && !has_advisories { + return Ok(PhpMixed::List(vec![ + Box::new(PhpMixed::Null), + Box::new(PhpMixed::String(packages_source)), + ])); + } + + Ok(PhpMixed::List(vec![ + Box::new(response_data), + Box::new(PhpMixed::String(packages_source)), + ])) } /// @param name package name (must be lowercased already) @@ -3293,18 +3280,20 @@ impl ComposerRepository { if self.packagesNotFoundCache.contains_key(filename) { let mut empty: IndexMap<String, PhpMixed> = IndexMap::new(); empty.insert("packages".to_string(), PhpMixed::Array(IndexMap::new())); - return Ok(react_promise_resolve(PhpMixed::Array( + return Ok(PhpMixed::Array( empty.into_iter().map(|(k, v)| (k, Box::new(v))).collect(), - ))); + )); } if self.freshMetadataUrls.contains_key(filename) && last_modified_time.is_some() { // make it look like we got a 304 response - let promise = react_promise_resolve(PhpMixed::Bool(true)); - - return Ok(promise); + return Ok(PhpMixed::Bool(true)); } + // TODO(phase-c-promise): the live fetch path builds accept/reject closures (with raw-pointer + // shared state) and returns http_downloader.add(...).then_with_reject_boxed(accept, reject). + // Rewrite as an async fetch + inline accept/reject handling once the HttpDownloader async + // boundary lands. let mut filename = filename.to_string(); let mut options = self.options.clone(); if let Some(dispatcher) = self.event_dispatcher.as_ref() { |
