From f31b101ce1e921a026ba234b1f0a83b0392bc118 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 20 May 2026 08:33:49 +0900 Subject: fix(compile): fix all remaining compile errors Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/shirabe-php-shim/src/lib.rs | 162 ++++++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 4 deletions(-) (limited to 'crates/shirabe-php-shim/src') diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs index 6b2d790..f01f16c 100644 --- a/crates/shirabe-php-shim/src/lib.rs +++ b/crates/shirabe-php-shim/src/lib.rs @@ -1,7 +1,8 @@ use indexmap::IndexMap; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub enum PhpMixed { + #[default] Null, Bool(bool), Int(i64), @@ -84,6 +85,15 @@ impl PhpMixed { matches!(self, PhpMixed::Null) } + /// Treats PhpMixed::Null as None, everything else as Some. + pub fn is_none(&self) -> bool { + self.is_null() + } + + pub fn is_some(&self) -> bool { + !self.is_null() + } + pub fn as_string_opt(&self) -> Option<&str> { self.as_string() } @@ -100,6 +110,49 @@ impl PhpMixed { pub fn unwrap_or(self, default: PhpMixed) -> PhpMixed { if self.is_null() { default } else { self } } + + pub fn unwrap_or_default(self) -> PhpMixed { + if self.is_null() { PhpMixed::Null } else { self } + } + + pub fn unwrap(self) -> PhpMixed { + if self.is_null() { + panic!("called `PhpMixed::unwrap()` on a `Null` value"); + } + self + } + + pub fn as_ref(&self) -> Option<&PhpMixed> { + self.as_opt() + } + + /// Treats PhpMixed::Null as None and applies the function for chaining. + pub fn and_then Option>(&self, f: F) -> Option { + self.as_opt().and_then(f) + } + + /// Counterpart to `Any::as_any` for trait-object call sites that downcast. + pub fn as_any(&self) -> &dyn std::any::Any { + self + } + + /// Treats `Null` and `Bool(false)` as the falsy case, anything else as Some. + pub fn ok_or_else E>(self, err: F) -> Result { + match self { + PhpMixed::Null | PhpMixed::Bool(false) => Err(err()), + v => Ok(v), + } + } + + /// PHP duck-typed helper-set entry. Real implementation lives in QuestionHelper. + pub fn ask( + &self, + _input: &dyn std::any::Any, + _output: &mut dyn std::any::Any, + _question: &dyn std::any::Any, + ) -> PhpMixed { + todo!() + } } impl From for PhpMixed { @@ -167,6 +220,15 @@ where } } +impl From> for PhpMixed +where + T: Into, +{ + fn from(value: Box) -> Self { + (*value).into() + } +} + impl std::fmt::Display for PhpMixed { fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { todo!() @@ -428,6 +490,18 @@ pub fn get_class(_object: &PhpMixed) -> String { todo!() } +// Overload accepting an `anyhow::Error` (PHP's `get_class($e)` is commonly used on exceptions). +pub fn get_class_err(_e: &anyhow::Error) -> String { + todo!() +} + +/// Overload accepting any object reference. PHP's `get_class($obj)` returns the +/// class name; in Rust we don't have a runtime class name, so this stub is left +/// as `todo!()`. +pub fn get_class_obj(_object: &T) -> String { + todo!() +} + pub fn get_debug_type(_value: &PhpMixed) -> String { todo!() } @@ -1387,9 +1461,9 @@ pub fn reset(_array: &[T]) -> Option { pub const OPENSSL_ALGO_SHA384: i64 = 9; pub fn array_intersect_key( - _array1: &IndexMap>, - _array2: &IndexMap>, -) -> IndexMap> { + _array1: &IndexMap, + _array2: &IndexMap, +) -> IndexMap { todo!() } @@ -1658,6 +1732,16 @@ where todo!() } +pub fn array_filter_map( + _array: &IndexMap>, + _callback: F, +) -> IndexMap +where + F: Fn(&PhpMixed) -> bool, +{ + todo!() +} + pub fn array_all(_array: &[T], _callback: F) -> bool where F: Fn(&T) -> bool, @@ -1695,6 +1779,10 @@ pub fn clearstatcache() { todo!() } +pub fn clearstatcache2(_clear_realpath_cache: bool, _filename: &str) { + todo!() +} + pub fn disk_free_space(_directory: &str) -> Option { todo!() } @@ -1717,6 +1805,10 @@ pub fn array_flip(_array: &PhpMixed) -> PhpMixed { todo!() } +pub fn array_flip_strings(_array: &[String]) -> IndexMap { + todo!() +} + pub fn max(_a: i64, _b: i64) -> i64 { todo!() } @@ -1945,6 +2037,44 @@ pub struct RecursiveIteratorIterator; impl RecursiveIteratorIterator { pub const SELF_FIRST: i64 = 0; pub const CHILD_FIRST: i64 = 16; + + pub fn get_sub_pathname(&self) -> String { + todo!() + } +} + +impl IntoIterator for &RecursiveIteratorIterator { + type Item = RecursiveIteratorFileInfo; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} + +#[derive(Debug)] +pub struct RecursiveIteratorFileInfo; + +impl RecursiveIteratorFileInfo { + pub fn is_dir(&self) -> bool { + todo!() + } + + pub fn is_file(&self) -> bool { + todo!() + } + + pub fn is_link(&self) -> bool { + todo!() + } + + pub fn get_pathname(&self) -> String { + todo!() + } + + pub fn get_size(&self) -> i64 { + todo!() + } } pub fn recursive_directory_iterator(_path: &str, _flags: i64) -> RecursiveDirectoryIterator { @@ -2161,6 +2291,10 @@ impl ArrayObject { pub fn new(_array: Option) -> Self { todo!() } + + pub fn to_array(&self) -> IndexMap> { + self.data.clone() + } } #[derive(Debug)] @@ -2175,3 +2309,23 @@ pub struct StdClass { #[derive(Debug)] pub struct PhpResource; + +pub fn gethostbyname(_hostname: &str) -> String { + todo!() +} + +pub fn http_get_last_response_headers() -> Option> { + todo!() +} + +pub fn http_clear_last_response_headers() { + todo!() +} + +pub fn zlib_decode(_data: &str) -> Option { + todo!() +} + +pub const STREAM_NOTIFY_FAILURE: i64 = 9; +pub const STREAM_NOTIFY_FILE_SIZE_IS: i64 = 5; +pub const STREAM_NOTIFY_PROGRESS: i64 = 7; -- cgit v1.3.1