aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-external-packages/src/symfony/console/helper/symfony_question_helper.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-01 20:51:40 +0900
committernsfisis <nsfisis@gmail.com>2026-08-01 20:51:40 +0900
commite5e6cc6807c9fbbef883ffe0eec9eed477d5bee3 (patch)
tree8d5f1ff760e56b370c53ac0311c219ee7a7988c2 /crates/shirabe-external-packages/src/symfony/console/helper/symfony_question_helper.rs
parent06d2c5c884eee0b5b663730f4d379a7ceae3a8e4 (diff)
downloadphp-shirabe-e5e6cc6807c9fbbef883ffe0eec9eed477d5bee3.tar.gz
php-shirabe-e5e6cc6807c9fbbef883ffe0eec9eed477d5bee3.tar.zst
php-shirabe-e5e6cc6807c9fbbef883ffe0eec9eed477d5bee3.zip
feat(symfony-console): implement interactive question/style helpers
Resolve the remaining todo!()s in SymfonyStyle, OutputStyle, QuestionHelper and SymfonyQuestionHelper: * Wire up the virtual dispatch PHP performs for the protected writePrompt()/writeError() overrides, following the codebase's established inheritance idiom (Command, ArchiveDownloader): the base class becomes a trait (QuestionHelperInterface, named after the QuestionInterface precedent) whose provided methods ask/do_ask/ validate_attempts carry the template logic and late-bind the write_prompt/write_error hooks through Self, with inner()/inner_mut() reaching the base-class state. SymfonyQuestionHelper overrides the hooks as plain trait-impl methods, mirroring PHP's protected-method overriding, so SymfonyStyle-driven questions now render the Symfony Style Guide prompt. * Type definition_list input as an enum (string|array|TableSeparator) because PhpMixed intentionally cannot carry objects; the InvalidArgumentException branch (a LogicException) becomes unrepresentable. horizontal_table now takes typed Cells/Rows. * Propagate the MissingInputException thrown inside autocomplete() through a Result instead of aborting. * Implement as_console_output_interface via Ref::filter_map on ConsoleOutput, the interface's only implementor. * Port progressIterate eagerly, following ProgressBar::iterate. * Map __FILE__ to current_exe(): a native binary never runs from a phar, so the hiddeninput.exe relocation branch correctly never fires. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-external-packages/src/symfony/console/helper/symfony_question_helper.rs')
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/helper/symfony_question_helper.rs56
1 files changed, 32 insertions, 24 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/helper/symfony_question_helper.rs b/crates/shirabe-external-packages/src/symfony/console/helper/symfony_question_helper.rs
index 086f9c1c..cae3434d 100644
--- a/crates/shirabe-external-packages/src/symfony/console/helper/symfony_question_helper.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/helper/symfony_question_helper.rs
@@ -1,10 +1,11 @@
//! ref: composer/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
use crate::symfony::console::formatter::output_formatter::OutputFormatter;
-use crate::symfony::console::helper::question_helper::QuestionHelper;
+use crate::symfony::console::helper::question_helper::{QuestionHelper, QuestionHelperInterface};
use crate::symfony::console::output::output_interface;
use crate::symfony::console::output::output_interface::OutputInterface;
use crate::symfony::console::question::QuestionInterface;
+use crate::symfony::console::style::style_interface::StyleInterface;
use crate::symfony::console::style::symfony_style::SymfonyStyle;
use shirabe_php_shim::PhpMixed;
use std::ops::{Deref, DerefMut};
@@ -20,7 +21,26 @@ impl SymfonyQuestionHelper {
Self::default()
}
- pub(crate) fn write_prompt(
+ fn get_eof_shortcut(&self) -> String {
+ if shirabe_php_shim::php_os_family() == "Windows" {
+ return "<comment>Ctrl+Z</comment> then <comment>Enter</comment>".to_string();
+ }
+
+ "<comment>Ctrl+D</comment>".to_string()
+ }
+}
+
+impl QuestionHelperInterface for SymfonyQuestionHelper {
+ fn inner(&self) -> &QuestionHelper {
+ &self.inner
+ }
+
+ fn inner_mut(&mut self) -> &mut QuestionHelper {
+ &mut self.inner
+ }
+
+ /// {@inheritdoc}
+ fn write_prompt(
&self,
output: std::rc::Rc<std::cell::RefCell<dyn OutputInterface>>,
question: &impl QuestionInterface,
@@ -108,35 +128,23 @@ impl SymfonyQuestionHelper {
.write(&[prompt], false, output_interface::OUTPUT_NORMAL);
}
- pub(crate) fn write_error(
+ /// {@inheritdoc}
+ fn write_error(
&self,
output: std::rc::Rc<std::cell::RefCell<dyn OutputInterface>>,
error: &shirabe_php_shim::Exception,
) {
- let is_symfony_style = {
- let borrowed = output.borrow();
- (*borrowed)
- .as_any()
- .downcast_ref::<SymfonyStyle>()
- .is_some()
- };
- if is_symfony_style {
- // $output->newLine(); $output->error($error->getMessage());
- // SymfonyStyle's newLine()/error() require mutable access to the
- // concrete type; mutable downcasting through the trait object is
- // resolved in a later phase.
- todo!("SymfonyStyle newLine()/error() require &mut SymfonyStyle");
- }
-
- self.inner.write_error(output, error);
- }
+ {
+ let mut borrowed = output.borrow_mut();
+ if let Some(style) = (*borrowed).as_any_mut().downcast_mut::<SymfonyStyle>() {
+ style.new_line(1);
+ style.error(PhpMixed::String(error.message.clone()));
- fn get_eof_shortcut(&self) -> String {
- if shirabe_php_shim::php_os_family() == "Windows" {
- return "<comment>Ctrl+Z</comment> then <comment>Enter</comment>".to_string();
+ return;
+ }
}
- "<comment>Ctrl+D</comment>".to_string()
+ self.inner.write_error(output, error);
}
}