aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/plugin/php_plugin_value.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-31 00:15:52 +0900
committernsfisis <nsfisis@gmail.com>2026-08-31 00:15:52 +0900
commit6a6ec1b8f8a5c70d21f3772ce637b763e8ab21ea (patch)
tree5a23dda75a0a8eb39478b77da82cf582e21a1d2c /crates/shirabe/src/plugin/php_plugin_value.rs
parentdc1f030e3904677cd65eac0a90c1d850e0ad1bbf (diff)
downloadphp-shirabe-6a6ec1b8f8a5c70d21f3772ce637b763e8ab21ea.tar.gz
php-shirabe-6a6ec1b8f8a5c70d21f3772ce637b763e8ab21ea.tar.zst
php-shirabe-6a6ec1b8f8a5c70d21f3772ce637b763e8ab21ea.zip
feat(plugin): carry Http\Response across as a materialized value
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) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/plugin/php_plugin_value.rs')
-rw-r--r--crates/shirabe/src/plugin/php_plugin_value.rs44
1 files changed, 44 insertions, 0 deletions
diff --git a/crates/shirabe/src/plugin/php_plugin_value.rs b/crates/shirabe/src/plugin/php_plugin_value.rs
index cb9b990e..80415eef 100644
--- a/crates/shirabe/src/plugin/php_plugin_value.rs
+++ b/crates/shirabe/src/plugin/php_plugin_value.rs
@@ -14,6 +14,7 @@
//! constraint) has no faithful constructor call.
use crate::package::Link;
+use crate::util::http::Response;
use chrono::{DateTime, NaiveDateTime, TimeZone, Utc};
use shirabe_php_rpc::{PhpObject, PhpThrow, PluginValue};
use shirabe_semver::constraint::{
@@ -21,6 +22,7 @@ use shirabe_semver::constraint::{
};
const LINK_CLASS: &str = "Composer\\Package\\Link";
+const RESPONSE_CLASS: &str = "Composer\\Util\\Http\\Response";
const CONSTRAINT_CLASS: &str = "Composer\\Semver\\Constraint\\Constraint";
const MULTI_CONSTRAINT_CLASS: &str = "Composer\\Semver\\Constraint\\MultiConstraint";
const MATCH_ALL_CLASS: &str = "Composer\\Semver\\Constraint\\MatchAllConstraint";
@@ -197,6 +199,48 @@ fn constraint_from_wire(value: &PluginValue) -> Result<AnyConstraint, PhpThrow>
})
}
+/// A `Response` is built for one request and never retained by the object graph, so the child
+/// holds a real instance rather than a handle, and `collect()` frees the copy it holds.
+///
+/// TODO(type-model): PHP's `$request` is the whole request array (`url`, `options`, `copyTo`)
+/// and this port keeps only the url, which is all `decodeJson()` reads back out of it.
+///
+/// TODO(port): Composer answers a curl request with a `Composer\Util\Http\CurlResponse`
+/// carrying the transfer info; this port flattens that subclass into `Response` before the
+/// value leaves `HttpDownloader`, so `getCurlInfo()` is gone and `get_class()` differs.
+pub(crate) fn response_to_wire(response: &Response) -> PluginValue {
+ let mut object = PhpObject::new(RESPONSE_CLASS);
+ let mut request = indexmap::IndexMap::new();
+ request.insert(b"url".to_vec(), PluginValue::string(response.request_url()));
+ object.set_private(RESPONSE_CLASS, "request", PluginValue::Array(request));
+ object.set_private(
+ RESPONSE_CLASS,
+ "code",
+ PluginValue::Int(response.get_status_code()),
+ );
+ object.set_private(
+ RESPONSE_CLASS,
+ "headers",
+ PluginValue::List(
+ response
+ .get_headers()
+ .iter()
+ .cloned()
+ .map(PluginValue::string)
+ .collect(),
+ ),
+ );
+ object.set_private(
+ RESPONSE_CLASS,
+ "body",
+ match response.get_body() {
+ Some(body) => PluginValue::string(body),
+ None => PluginValue::Null,
+ },
+ );
+ PluginValue::PhpObject(object)
+}
+
pub(crate) fn link_to_wire(link: &Link) -> PluginValue {
let mut object = PhpObject::new(LINK_CLASS);
object.set_protected("source", PluginValue::string(link.get_source()));