From c1eb810304a1075ac7c37a69aeaf6ecef01a1eff Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 15 May 2026 00:31:59 +0900 Subject: feat(port): port BufferIO.php Add fseek, rewind, strip_tags shim functions and PHP_EOL constant. --- crates/shirabe-php-shim/src/lib.rs | 14 ++++++ crates/shirabe/src/io/buffer_io.rs | 100 +++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) (limited to 'crates') diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs index 06dd64a..48508a4 100644 --- a/crates/shirabe-php-shim/src/lib.rs +++ b/crates/shirabe-php-shim/src/lib.rs @@ -141,6 +141,20 @@ pub fn gzclose(file: PhpMixed) { todo!() } +pub fn fseek(stream: PhpMixed, offset: i64) -> i64 { + todo!() +} + +pub fn rewind(stream: PhpMixed) -> bool { + todo!() +} + +pub fn strip_tags(str: &str) -> String { + todo!() +} + +pub const PHP_EOL: &str = "\n"; + pub fn fopen(file: &str, mode: &str) -> PhpMixed { todo!() } diff --git a/crates/shirabe/src/io/buffer_io.rs b/crates/shirabe/src/io/buffer_io.rs index 409244b..30e2aeb 100644 --- a/crates/shirabe/src/io/buffer_io.rs +++ b/crates/shirabe/src/io/buffer_io.rs @@ -1 +1,101 @@ //! ref: composer/src/Composer/IO/BufferIO.php + +use anyhow::Result; +use shirabe_external_packages::composer::pcre::preg::Preg; +use shirabe_external_packages::symfony::console::formatter::output_formatter_interface::OutputFormatterInterface; +use shirabe_external_packages::symfony::console::helper::helper_set::HelperSet; +use shirabe_external_packages::symfony::console::helper::question_helper::QuestionHelper; +use shirabe_external_packages::symfony::console::input::streamable_input_interface::StreamableInputInterface; +use shirabe_external_packages::symfony::console::input::string_input::StringInput; +use shirabe_external_packages::symfony::console::output::stream_output::StreamOutput; +use shirabe_php_shim::{fopen, fseek, fwrite, rewind, stream_get_contents, strip_tags, PhpMixed, RuntimeException, PHP_EOL}; +use crate::io::console_io::ConsoleIO; + +#[derive(Debug)] +pub struct BufferIO { + inner: ConsoleIO, +} + +impl BufferIO { + pub fn new(input: String, verbosity: i64, formatter: Option>) -> Result { + let mut input_obj = StringInput::new(input); + input_obj.set_interactive(false); + + let stream = fopen("php://memory", "rw"); + if matches!(stream, PhpMixed::Bool(false)) { + return Err(RuntimeException { + message: "Unable to open memory output stream".to_string(), + code: 0, + } + .into()); + } + + let decorated = formatter.as_ref().map_or(false, |f| f.is_decorated()); + let output = StreamOutput::new(stream, verbosity, decorated, formatter); + + let inner = ConsoleIO::new( + input_obj, + output, + HelperSet::new(vec![Box::new(QuestionHelper::new())]), + ); + + Ok(Self { inner }) + } + + pub fn get_output(&self) -> String { + fseek(self.inner.output.get_stream(), 0); + + let output = stream_get_contents(self.inner.output.get_stream()).unwrap_or_default(); + + let output = Preg::replace_callback( + r"{(?<=^|\n|\x08)(.+?)(\x08+)}", + |matches: &[String]| -> String { + let pre = strip_tags(&matches[1]); + + if pre.len() == matches[2].len() { + return String::new(); + } + + // TODO reverse parse the string, skipping span tags and \033\[([0-9;]+)m(.*?)\033\[0m style blobs + format!("{}\n", matches[1].trim_end()) + }, + &output, + ); + + output + } + + pub fn set_user_inputs(&mut self, inputs: Vec) -> Result<()> { + if self.inner.input.as_any().downcast_ref::().is_none() { + return Err(RuntimeException { + message: "Setting the user inputs requires at least the version 3.2 of the symfony/console component.".to_string(), + code: 0, + } + .into()); + } + + self.inner.input.set_stream(self.create_stream(inputs)?); + self.inner.input.set_interactive(true); + + Ok(()) + } + + fn create_stream(&self, inputs: Vec) -> Result { + let stream = fopen("php://memory", "r+"); + if matches!(stream, PhpMixed::Bool(false)) { + return Err(RuntimeException { + message: "Unable to open memory output stream".to_string(), + code: 0, + } + .into()); + } + + for input in inputs { + fwrite(stream.clone(), &format!("{}{}", input, PHP_EOL), -1); + } + + rewind(stream.clone()); + + Ok(stream) + } +} -- cgit v1.3.1