aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/io/buffer_io.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-20 08:33:49 +0900
committernsfisis <nsfisis@gmail.com>2026-05-20 08:33:57 +0900
commitf31b101ce1e921a026ba234b1f0a83b0392bc118 (patch)
treeb7ac2aa84d71ebd162cc21aeab0240e7e0544988 /crates/shirabe/src/io/buffer_io.rs
parent5e31fa33c3b5cf726a57a063b8e7a070869250fe (diff)
downloadphp-shirabe-f31b101ce1e921a026ba234b1f0a83b0392bc118.tar.gz
php-shirabe-f31b101ce1e921a026ba234b1f0a83b0392bc118.tar.zst
php-shirabe-f31b101ce1e921a026ba234b1f0a83b0392bc118.zip
fix(compile): fix all remaining compile errors
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/io/buffer_io.rs')
-rw-r--r--crates/shirabe/src/io/buffer_io.rs208
1 files changed, 179 insertions, 29 deletions
diff --git a/crates/shirabe/src/io/buffer_io.rs b/crates/shirabe/src/io/buffer_io.rs
index 79fa9c3..ce4070a 100644
--- a/crates/shirabe/src/io/buffer_io.rs
+++ b/crates/shirabe/src/io/buffer_io.rs
@@ -3,11 +3,12 @@
use crate::io::console_io::ConsoleIO;
use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::symfony::component::console::helper::helper_set::HelperSet;
+use shirabe_external_packages::symfony::component::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::component::console::input::string_input::StringInput;
+use shirabe_external_packages::symfony::component::console::output::output_interface::OutputInterface;
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::{
PHP_EOL, PhpMixed, RuntimeException, fopen, fseek, fwrite, rewind, stream_get_contents,
@@ -16,7 +17,7 @@ use shirabe_php_shim::{
#[derive(Debug)]
pub struct BufferIO {
- inner: ConsoleIO,
+ pub(crate) inner: ConsoleIO,
}
impl BufferIO {
@@ -25,7 +26,7 @@ impl BufferIO {
verbosity: i64,
formatter: Option<Box<dyn OutputFormatterInterface>>,
) -> Result<Self> {
- let mut input_obj = StringInput::new(input);
+ let mut input_obj = StringInput::new(&input);
input_obj.set_interactive(false);
let stream = fopen("php://memory", "rw");
@@ -38,21 +39,34 @@ impl BufferIO {
}
let decorated = formatter.as_ref().map_or(false, |f| f.is_decorated());
- let output = StreamOutput::new(stream, verbosity, decorated, formatter);
+ // TODO(phase-b): StreamOutput lives under `symfony::console` (not `symfony::component::console`)
+ // and so does not implement the `component::console::output::OutputInterface` ConsoleIO expects.
+ // Real fix requires unifying the two crate paths.
+ let _ = formatter;
+ let _ = StreamOutput::new(stream, verbosity, Some(decorated));
+ let output: Box<dyn OutputInterface> = todo!("StreamOutput as Box<dyn OutputInterface>");
+ // TODO(phase-b): symfony console helper modules live under both `symfony::console`
+ // and `symfony::component::console`; QuestionHelper::new is not yet provided.
+ let helpers: Vec<PhpMixed> = vec![/* PhpMixed::Object(QuestionHelper::new()) */];
+ let _ = std::marker::PhantomData::<QuestionHelper>;
let inner = ConsoleIO::new(
- input_obj,
+ Box::new(input_obj) as Box<dyn InputInterface>,
output,
- HelperSet::new(vec![Box::new(QuestionHelper::new())]),
+ HelperSet::new(helpers),
);
Ok(Self { inner })
}
pub fn get_output(&self) -> String {
- fseek(self.inner.output.get_stream(), 0);
+ // TODO(phase-b): OutputInterface::get_stream returns PhpResource, while
+ // fseek/stream_get_contents take PhpMixed. Conversion is not yet defined.
+ let stream: PhpMixed =
+ todo!("PhpResource -> PhpMixed conversion for OutputInterface::get_stream");
+ fseek(stream.clone(), 0);
- let output = stream_get_contents(self.inner.output.get_stream()).unwrap_or_default();
+ let output = stream_get_contents(stream).unwrap_or_default();
let output = Preg::replace_callback(
r"{(?<=^|\n|\x08)(.+?)(\x08+)}",
@@ -80,28 +94,19 @@ impl BufferIO {
&output,
);
- output
+ // TODO(phase-b): Preg::replace_callback returns Result<String>, unwrap for now
+ output.unwrap_or_default()
}
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(())
+ // TODO(phase-b): downcast Box<dyn InputInterface> to StreamableInputInterface.
+ // as_any/set_stream are not yet exposed on the InputInterface trait object.
+ let _ = inputs;
+ let _ = |i: &Box<dyn InputInterface>| -> bool {
+ let _ = i;
+ false
+ };
+ todo!("port BufferIO::set_user_inputs once StreamableInputInterface downcast is available")
}
fn create_stream(&self, inputs: Vec<String>) -> Result<PhpMixed> {
@@ -123,3 +128,148 @@ impl BufferIO {
Ok(stream)
}
}
+
+// TODO(phase-b): PHP `class BufferIO extends ConsoleIO` — delegate all IOInterface,
+// LoggerInterface, and BaseIO methods to `self.inner` (ConsoleIO).
+impl shirabe_external_packages::psr::log::logger_interface::LoggerInterface for BufferIO {
+ fn emergency(&self, message: &str, context: &[(&str, &str)]) {
+ self.inner.emergency(message, context)
+ }
+ fn alert(&self, message: &str, context: &[(&str, &str)]) {
+ self.inner.alert(message, context)
+ }
+ fn critical(&self, message: &str, context: &[(&str, &str)]) {
+ self.inner.critical(message, context)
+ }
+ fn error(&self, message: &str, context: &[(&str, &str)]) {
+ self.inner.error(message, context)
+ }
+ fn warning(&self, message: &str, context: &[(&str, &str)]) {
+ self.inner.warning(message, context)
+ }
+ fn notice(&self, message: &str, context: &[(&str, &str)]) {
+ self.inner.notice(message, context)
+ }
+ fn info(&self, message: &str, context: &[(&str, &str)]) {
+ self.inner.info(message, context)
+ }
+ fn debug(&self, message: &str, context: &[(&str, &str)]) {
+ self.inner.debug(message, context)
+ }
+ fn log(&self, level: &str, message: &str, context: &[(&str, &str)]) {
+ self.inner.log(level, message, context)
+ }
+}
+
+impl crate::io::io_interface::IOInterface for BufferIO {
+ fn is_interactive(&self) -> bool {
+ self.inner.is_interactive()
+ }
+ fn is_verbose(&self) -> bool {
+ self.inner.is_verbose()
+ }
+ fn is_very_verbose(&self) -> bool {
+ self.inner.is_very_verbose()
+ }
+ fn is_debug(&self) -> bool {
+ self.inner.is_debug()
+ }
+ fn is_decorated(&self) -> bool {
+ self.inner.is_decorated()
+ }
+ fn write3(&self, message: &str, newline: bool, verbosity: i64) {
+ self.inner.write3(message, newline, verbosity)
+ }
+ fn write_error3(&self, message: &str, newline: bool, verbosity: i64) {
+ self.inner.write_error3(message, newline, verbosity)
+ }
+ fn write_raw3(&self, message: &str, newline: bool, verbosity: i64) {
+ self.inner.write_raw3(message, newline, verbosity)
+ }
+ fn write_error_raw3(&self, message: &str, newline: bool, verbosity: i64) {
+ self.inner.write_error_raw3(message, newline, verbosity)
+ }
+ fn overwrite4(&self, message: &str, newline: bool, size: Option<i64>, verbosity: i64) {
+ self.inner.overwrite4(message, newline, size, verbosity)
+ }
+ fn overwrite_error4(&self, message: &str, newline: bool, size: Option<i64>, verbosity: i64) {
+ self.inner
+ .overwrite_error4(message, newline, size, verbosity)
+ }
+ fn ask(&self, question: String, default: PhpMixed) -> PhpMixed {
+ self.inner.ask(question, default)
+ }
+ fn ask_confirmation(&self, question: String, default: bool) -> bool {
+ self.inner.ask_confirmation(question, default)
+ }
+ fn ask_and_validate(
+ &self,
+ question: String,
+ validator: Box<dyn Fn(PhpMixed) -> PhpMixed>,
+ attempts: Option<i64>,
+ default: PhpMixed,
+ ) -> PhpMixed {
+ self.inner
+ .ask_and_validate(question, validator, attempts, default)
+ }
+ fn ask_and_hide_answer(&self, question: String) -> Option<String> {
+ self.inner.ask_and_hide_answer(question)
+ }
+ fn select(
+ &self,
+ question: String,
+ choices: Vec<String>,
+ default: PhpMixed,
+ attempts: PhpMixed,
+ error_message: String,
+ multiselect: bool,
+ ) -> PhpMixed {
+ self.inner.select(
+ question,
+ choices,
+ default,
+ attempts,
+ error_message,
+ multiselect,
+ )
+ }
+ fn get_authentications(
+ &self,
+ ) -> indexmap::IndexMap<String, indexmap::IndexMap<String, Option<String>>> {
+ self.inner.get_authentications()
+ }
+ fn has_authentication(&self, repository_name: &str) -> bool {
+ self.inner.has_authentication(repository_name)
+ }
+ fn get_authentication(
+ &self,
+ repository_name: &str,
+ ) -> indexmap::IndexMap<String, Option<String>> {
+ self.inner.get_authentication(repository_name)
+ }
+ fn set_authentication(
+ &mut self,
+ repository_name: String,
+ username: String,
+ password: Option<String>,
+ ) {
+ self.inner
+ .set_authentication(repository_name, username, password)
+ }
+ fn load_configuration(&mut self, config: &mut crate::config::Config) -> anyhow::Result<()> {
+ self.inner.load_configuration(config)
+ }
+}
+
+impl crate::io::base_io::BaseIO for BufferIO {
+ fn authentications(
+ &self,
+ ) -> &indexmap::IndexMap<String, indexmap::IndexMap<String, Option<String>>> {
+ self.inner.authentications()
+ }
+ fn authentications_mut(
+ &mut self,
+ ) -> &mut indexmap::IndexMap<String, indexmap::IndexMap<String, Option<String>>> {
+ self.inner.authentications_mut()
+ }
+}