diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-29 02:27:44 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-29 02:28:08 +0900 |
| commit | 27e02b6c8968f89cf601ef597fcefa6a9627718e (patch) | |
| tree | 4b7d8c00a2a46b94425fd4b4afc976b75d285c07 | |
| parent | 3b28fc65f5de7c6ad69bee48b2d1f52dd9b30972 (diff) | |
| download | php-shirabe-27e02b6c8968f89cf601ef597fcefa6a9627718e.tar.gz php-shirabe-27e02b6c8968f89cf601ef597fcefa6a9627718e.tar.zst php-shirabe-27e02b6c8968f89cf601ef597fcefa6a9627718e.zip | |
feat(console): implement output instanceof downcasts in process/progress helpers
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| -rw-r--r-- | crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs | 32 | ||||
| -rw-r--r-- | crates/shirabe-external-packages/src/symfony/console/helper/progress_bar.rs | 35 |
2 files changed, 44 insertions, 23 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs b/crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs index 10fff08..28e2329 100644 --- a/crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs +++ b/crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs @@ -4,6 +4,7 @@ use crate::symfony::console::helper::debug_formatter_helper::DebugFormatterHelpe use crate::symfony::console::helper::helper::Helper; use crate::symfony::console::helper::helper_interface::HelperInterface; use crate::symfony::console::helper::helper_set::HelperSet; +use crate::symfony::console::output::ConsoleOutputInterface; use crate::symfony::console::output::output_interface::{self, OutputInterface}; use crate::symfony::process::exception::process_failed_exception::ProcessFailedException; use crate::symfony::process::process::Process; @@ -50,11 +51,15 @@ impl ProcessHelper { // component being absent; in this port the component is always available. // PHP: `if ($output instanceof ConsoleOutputInterface) { $output = - // $output->getErrorOutput(); }`. Downcasting a shared `dyn - // OutputInterface` to `dyn ConsoleOutputInterface` is unresolved; - // deferred to Phase C. - let output: Rc<RefCell<dyn OutputInterface>> = - todo!("$output instanceof ConsoleOutputInterface redirect to error output"); + // $output->getErrorOutput(); }`. ConsoleOutput is the only OutputInterface + // implementor that also implements ConsoleOutputInterface, so the check + // reduces to a downcast to the concrete type. + let output: Rc<RefCell<dyn OutputInterface>> = { + let redirected = shirabe_php_shim::AsAny::as_any(&*output.borrow()) + .downcast_ref::<crate::symfony::console::output::console_output::ConsoleOutput>() + .map(|console| console.get_error_output()); + redirected.unwrap_or(output) + }; let formatter: Rc<RefCell<DebugFormatterHelper>> = self .get_helper_set() @@ -220,15 +225,18 @@ impl ProcessHelper { &self, output: Rc<RefCell<dyn OutputInterface>>, process: &Process, - // TODO: remove allow(unused_mut) once todo!() is resolved. - #[allow(unused_mut)] mut callback: Option<Box<dyn FnMut(&str, &str)>>, + mut callback: Option<Box<dyn FnMut(&str, &str)>>, ) -> Box<dyn FnMut(&str, &str)> { // PHP: `if ($output instanceof ConsoleOutputInterface) { $output = - // $output->getErrorOutput(); }`. Downcasting a shared `dyn - // OutputInterface` to `dyn ConsoleOutputInterface` is unresolved; - // deferred to Phase C. - let output: Rc<RefCell<dyn OutputInterface>> = - todo!("$output instanceof ConsoleOutputInterface redirect to error output"); + // $output->getErrorOutput(); }`. ConsoleOutput is the only OutputInterface + // implementor that also implements ConsoleOutputInterface, so the check + // reduces to a downcast to the concrete type. + let output: Rc<RefCell<dyn OutputInterface>> = { + let redirected = shirabe_php_shim::AsAny::as_any(&*output.borrow()) + .downcast_ref::<crate::symfony::console::output::console_output::ConsoleOutput>() + .map(|console| console.get_error_output()); + redirected.unwrap_or(output) + }; let formatter: Rc<RefCell<DebugFormatterHelper>> = self .get_helper_set() diff --git a/crates/shirabe-external-packages/src/symfony/console/helper/progress_bar.rs b/crates/shirabe-external-packages/src/symfony/console/helper/progress_bar.rs index aa7e326..a18e62f 100644 --- a/crates/shirabe-external-packages/src/symfony/console/helper/progress_bar.rs +++ b/crates/shirabe-external-packages/src/symfony/console/helper/progress_bar.rs @@ -3,6 +3,8 @@ use crate::symfony::console::cursor::Cursor; use crate::symfony::console::exception::logic_exception::LogicException; use crate::symfony::console::helper::helper::Helper; +use crate::symfony::console::output::ConsoleOutputInterface; +use crate::symfony::console::output::ConsoleSectionOutput; use crate::symfony::console::output::OutputInterface; use crate::symfony::console::output::output_interface; use crate::symfony::console::terminal::Terminal; @@ -67,10 +69,15 @@ impl ProgressBar { max: i64, min_seconds_between_redraws: f64, ) -> Self { - let output = if todo!("$output instanceof ConsoleOutputInterface") { - todo!("$output = $output->getErrorOutput();") - } else { - output + // PHP: `if ($output instanceof ConsoleOutputInterface) { $output = + // $output->getErrorOutput(); }`. ConsoleOutput is the only OutputInterface + // implementor that also implements ConsoleOutputInterface, so the check + // reduces to a downcast to the concrete type. + let output: Rc<RefCell<dyn OutputInterface>> = { + let redirected = shirabe_php_shim::AsAny::as_any(&*output.borrow()) + .downcast_ref::<crate::symfony::console::output::console_output::ConsoleOutput>() + .map(|console| console.get_error_output()); + redirected.unwrap_or(output) }; let mut this = Self { @@ -502,12 +509,18 @@ impl ProgressBar { if self.overwrite { if let Some(previous_message) = self.previous_message.clone() { - if todo!("$this->output instanceof ConsoleSectionOutput") { + // PHP: `$this->output instanceof ConsoleSectionOutput`. Downcast the + // shared output handle to the concrete section type. + let output_ref = self.output.borrow(); + if let Some(section) = shirabe_php_shim::AsAny::as_any(&*output_ref) + .downcast_ref::<ConsoleSectionOutput>() + { let message_lines = shirabe_php_shim::explode("\n", &previous_message); let mut line_count = message_lines.len() as i64; for message_line in &message_lines { + let formatter = section.get_formatter(); let message_line_length = Helper::width(&Helper::remove_decoration( - todo!("$this->output->getFormatter()"), + &mut *formatter.borrow_mut(), message_line, )); if message_line_length > self.terminal.get_width() { @@ -516,8 +529,9 @@ impl ProgressBar { .floor() as i64; } } - todo!("$this->output->clear($lineCount); (ConsoleSectionOutput)"); + section.clear(Some(line_count)); } else { + drop(output_ref); let line_count = shirabe_php_shim::substr_count(&previous_message, "\n"); for _i in 0..line_count { self.cursor.move_to_column(1); @@ -584,7 +598,7 @@ impl ProgressBar { Box::new( |bar: &ProgressBar, output: &Rc<RefCell<dyn OutputInterface>>| { let complete_bars = bar.get_bar_offset(); - let display = shirabe_php_shim::str_repeat( + let mut display = shirabe_php_shim::str_repeat( &bar.get_bar_character(), complete_bars as usize, ); @@ -592,7 +606,7 @@ impl ProgressBar { let empty_bars = bar.get_bar_width() as f64 - complete_bars - Helper::length(&Helper::remove_decoration( - todo!("$output->getFormatter()"), + &mut *output.borrow().get_formatter().borrow_mut(), &bar.get_progress_character(), )) as f64; display.push_str(&format!( @@ -603,7 +617,6 @@ impl ProgressBar { empty_bars as usize ) )); - let _ = output; } Ok(Ok(shirabe_php_shim::PhpMixed::String(display))) @@ -762,7 +775,7 @@ impl ProgressBar { .iter() .map(|sub_line| { Helper::width(&Helper::remove_decoration( - todo!("$this->output->getFormatter()"), + &mut *self.output.borrow().get_formatter().borrow_mut(), &shirabe_php_shim::rtrim(sub_line, Some("\r")), )) }) |
