aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-shim/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-21 18:49:24 +0900
committernsfisis <nsfisis@gmail.com>2026-06-21 18:52:05 +0900
commita3171eefd8f8e520329bdd8f613e83ba6f0a7c13 (patch)
tree195599a0c46b97349f017b97e965e4b4c1794f36 /crates/shirabe-php-shim/src
parente24bf7e3b6b16a77c2eaeae9ba7b453f5138ff25 (diff)
downloadphp-shirabe-a3171eefd8f8e520329bdd8f613e83ba6f0a7c13.tar.gz
php-shirabe-a3171eefd8f8e520329bdd8f613e83ba6f0a7c13.tar.zst
php-shirabe-a3171eefd8f8e520329bdd8f613e83ba6f0a7c13.zip
refactor(php-shim): remove ArrayObject, inline IndexMap into PhpMixed::Object
ArrayObject was only a thin wrapper around IndexMap<String, PhpMixed> used as an empty-{} vs empty-[] marker and as the assoc=false JSON object representation; no reference semantics were involved. Inline its payload directly into PhpMixed::Object and drop the type along with the now-dead StdClass. Side effects of the unification: - ArrayObject::new was todo!(); the config --global / object-typed get paths that built PhpMixed::Object(ArrayObject::new(None)) no longer panic. - base_config_command wrote 'config' as PhpMixed::Array(empty), emitting [] instead of {}; now matches PHP's new \ArrayObject ({}). - The dead is::<StdClass>()/is::<ArrayObject>() instanceof checks in JsonManipulator are replaced with the faithful as_object() mapping. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-php-shim/src')
-rw-r--r--crates/shirabe-php-shim/src/array.rs2
-rw-r--r--crates/shirabe-php-shim/src/json.rs7
-rw-r--r--crates/shirabe-php-shim/src/lib.rs69
3 files changed, 19 insertions, 59 deletions
diff --git a/crates/shirabe-php-shim/src/array.rs b/crates/shirabe-php-shim/src/array.rs
index 4b3e160..8c1988d 100644
--- a/crates/shirabe-php-shim/src/array.rs
+++ b/crates/shirabe-php-shim/src/array.rs
@@ -568,7 +568,7 @@ pub fn count(value: &PhpMixed) -> usize {
match value {
PhpMixed::List(items) => items.len(),
PhpMixed::Array(entries) => entries.len(),
- PhpMixed::Object(object) => object.count(),
+ PhpMixed::Object(object) => object.len(),
// PHP 8 throws a `TypeError` for non-countable arguments.
PhpMixed::Null
| PhpMixed::Bool(_)
diff --git a/crates/shirabe-php-shim/src/json.rs b/crates/shirabe-php-shim/src/json.rs
index 23c4c41..3d3ee5b 100644
--- a/crates/shirabe-php-shim/src/json.rs
+++ b/crates/shirabe-php-shim/src/json.rs
@@ -1,4 +1,3 @@
-use crate::ArrayObject;
use crate::PhpMixed;
use indexmap::IndexMap;
@@ -58,7 +57,7 @@ pub fn json_encode_ex<T: serde::Serialize + ?Sized>(
// PHP's two-argument `json_decode`: without JSON_THROW_ON_ERROR it never throws,
// returning null on malformed input. With `assoc` false, JSON objects decode to
-// stdClass-equivalent ArrayObject values; with `assoc` true, to associative arrays.
+// stdClass-equivalent `PhpMixed::Object` values; with `assoc` true, to associative arrays.
pub fn json_decode(s: &str, assoc: bool) -> anyhow::Result<PhpMixed> {
match serde_json::from_str::<serde_json::Value>(s) {
Ok(value) => Ok(json_value_to_php_mixed(value, assoc)),
@@ -91,9 +90,7 @@ fn json_value_to_php_mixed(value: serde_json::Value, assoc: bool) -> PhpMixed {
if assoc {
PhpMixed::Array(data)
} else {
- PhpMixed::Object(ArrayObject {
- data: data.into_iter().collect(),
- })
+ PhpMixed::Object(data)
}
}
}
diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs
index b42ed75..0d7f8ef 100644
--- a/crates/shirabe-php-shim/src/lib.rs
+++ b/crates/shirabe-php-shim/src/lib.rs
@@ -62,7 +62,8 @@ pub enum PhpMixed {
String(String),
List(Vec<PhpMixed>),
Array(IndexMap<String, PhpMixed>),
- Object(ArrayObject),
+ // TODO: consolidate Object to Array.
+ Object(IndexMap<String, PhpMixed>),
}
impl serde::Serialize for PhpMixed {
@@ -91,7 +92,13 @@ impl serde::Serialize for PhpMixed {
}
map.end()
}
- PhpMixed::Object(object) => object.serialize(serializer),
+ PhpMixed::Object(entries) => {
+ let mut map = serializer.serialize_map(Some(entries.len()))?;
+ for (k, v) in entries {
+ map.serialize_entry(k, v)?;
+ }
+ map.end()
+ }
}
}
}
@@ -112,37 +119,17 @@ impl PartialEq for PhpMixed {
.zip(b.iter())
.all(|((ka, va), (kb, vb))| ka == kb && va == vb)
}
- (PhpMixed::Object(a), PhpMixed::Object(b)) => a == b,
+ (PhpMixed::Object(a), PhpMixed::Object(b)) => {
+ a.len() == b.len()
+ && a.iter()
+ .zip(b.iter())
+ .all(|((ka, va), (kb, vb))| ka == kb && va == vb)
+ }
_ => false,
}
}
}
-impl PartialEq for ArrayObject {
- fn eq(&self, other: &Self) -> bool {
- self.data.len() == other.data.len()
- && self
- .data
- .iter()
- .zip(other.data.iter())
- .all(|((ka, va), (kb, vb))| ka == kb && va == vb)
- }
-}
-
-impl serde::Serialize for ArrayObject {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: serde::Serializer,
- {
- use serde::ser::SerializeMap;
- let mut map = serializer.serialize_map(Some(self.data.len()))?;
- for (k, v) in &self.data {
- map.serialize_entry(k, v)?;
- }
- map.end()
- }
-}
-
impl PhpMixed {
pub fn as_bool(&self) -> Option<bool> {
match self {
@@ -200,7 +187,7 @@ impl PhpMixed {
}
}
- pub fn as_object(&self) -> Option<&ArrayObject> {
+ pub fn as_object(&self) -> Option<&IndexMap<String, PhpMixed>> {
match self {
PhpMixed::Object(o) => Some(o),
_ => None,
@@ -352,30 +339,6 @@ impl std::fmt::Display for PhpMixed {
}
#[derive(Debug, Clone)]
-pub struct ArrayObject {
- data: IndexMap<String, PhpMixed>,
-}
-
-impl ArrayObject {
- pub fn new(_array: Option<PhpMixed>) -> Self {
- todo!()
- }
-
- pub fn to_array(&self) -> IndexMap<String, PhpMixed> {
- self.data.clone()
- }
-
- pub fn count(&self) -> usize {
- self.data.len()
- }
-}
-
-#[derive(Debug)]
-pub struct StdClass {
- pub data: IndexMap<String, PhpMixed>,
-}
-
-#[derive(Debug, Clone)]
pub enum PhpResource {
Stdin,
Stdout,