aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/io
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-15 00:31:59 +0900
committernsfisis <nsfisis@gmail.com>2026-05-15 02:37:37 +0900
commitc1eb810304a1075ac7c37a69aeaf6ecef01a1eff (patch)
treebc5045b0ad80359bef3bc111bd9d8a2598a1adfb /crates/shirabe/src/io
parentb21e16434be1b7bf86a7fd31184998425a6ee9bf (diff)
downloadphp-shirabe-c1eb810304a1075ac7c37a69aeaf6ecef01a1eff.tar.gz
php-shirabe-c1eb810304a1075ac7c37a69aeaf6ecef01a1eff.tar.zst
php-shirabe-c1eb810304a1075ac7c37a69aeaf6ecef01a1eff.zip
feat(port): port BufferIO.php
Add fseek, rewind, strip_tags shim functions and PHP_EOL constant.
Diffstat (limited to 'crates/shirabe/src/io')
-rw-r--r--crates/shirabe/src/io/buffer_io.rs100
1 files changed, 100 insertions, 0 deletions
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<Box<dyn OutputFormatterInterface>>) -> Result<Self> {
+ 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<String>) -> Result<()> {
+ if self.inner.input.as_any().downcast_ref::<dyn StreamableInputInterface>().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<String>) -> Result<PhpMixed> {
+ 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)
+ }
+}