From 6a6ec1b8f8a5c70d21f3772ce637b763e8ab21ea Mon Sep 17 00:00:00 2001 From: nsfisis Date: Mon, 31 Aug 2026 00:15:52 +0900 Subject: feat(plugin): carry Http\Response across as a materialized value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A response is built for one request and the graph never retains it, so there is no entity for a handle to point at. The child holds a real instance instead, revived from the object record the wire carries, and collect() frees the copy each world holds — which is what that method is for. The value-object rule rejects the class only because collect() assigns to $this, so the category comes from an overrides.list entry. HttpDownloader::get() and copy() answer with one. Two gaps stay: decodeJson() reaches Composer\Json\JsonFile, which a guard shadows, and Composer answers a curl request with the CurlResponse subclass where this port flattens the value into a Response. Co-Authored-By: Claude Opus 5 (1M context) --- crates/shirabe/src/plugin/php_plugin_proxy.rs | 28 +++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'crates/shirabe/src/plugin/php_plugin_proxy.rs') diff --git a/crates/shirabe/src/plugin/php_plugin_proxy.rs b/crates/shirabe/src/plugin/php_plugin_proxy.rs index 491a320c..c966897b 100644 --- a/crates/shirabe/src/plugin/php_plugin_proxy.rs +++ b/crates/shirabe/src/plugin/php_plugin_proxy.rs @@ -21,7 +21,7 @@ use crate::package::{DisplayMode, PackageInterfaceHandle}; use crate::plugin::capability::{Capability, CommandProvider}; use crate::plugin::capable::Capable; use crate::plugin::php_plugin_value::{ - date_time_from_wire, date_time_to_wire, link_from_wire, link_to_wire, + date_time_from_wire, date_time_to_wire, link_from_wire, link_to_wire, response_to_wire, }; use crate::plugin::plugin_interface::PluginInterface; use crate::repository::{ @@ -1177,11 +1177,27 @@ fn dispatch_http_downloader_method( downloader.borrow_mut().set_options(options); Ok(PluginValue::Null) } - // TODO(plugin): a `Composer\Util\Http\Response` has no representation on the wire, so - // the two synchronous request methods have nothing to answer with. - "get" | "copy" => Err(runtime_throw(format!( - "Shirabe does not support HttpDownloader::{method_name}() from a plugin yet" - ))), + "get" => { + let url = arg::(method_name, args, 0)?; + let options = + arg_or::>(method_name, args, 1, IndexMap::new())?; + let response = downloader + .borrow() + .get(&url, options) + .map_err(|error| error_throw("get failed", &error))?; + Ok(response_to_wire(&response)) + } + "copy" => { + let url = arg::(method_name, args, 0)?; + let to = arg::(method_name, args, 1)?; + let options = + arg_or::>(method_name, args, 2, IndexMap::new())?; + let response = downloader + .borrow() + .copy(&url, &to, options) + .map_err(|error| error_throw("copy failed", &error))?; + Ok(response_to_wire(&response)) + } // TODO(plugin,async): the async surface resolves its promises with a Response the wire // cannot carry, and driving it needs a promise representation that crosses the boundary // unresolved. Neither exists yet. -- cgit v1.3.1-4-g156e