From 2ae4bfdd31dc6d2f0046f8c93a74ac6c0a4f59e9 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Thu, 14 May 2026 19:44:44 +0900 Subject: feat(port): port InputOption.php --- crates/shirabe/src/console/input/input_option.rs | 86 ++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'crates/shirabe') diff --git a/crates/shirabe/src/console/input/input_option.rs b/crates/shirabe/src/console/input/input_option.rs index 36d7846..069c3f4 100644 --- a/crates/shirabe/src/console/input/input_option.rs +++ b/crates/shirabe/src/console/input/input_option.rs @@ -1 +1,87 @@ //! ref: composer/src/Composer/Console/Input/InputOption.php + +use anyhow::Result; +use shirabe_external_packages::symfony::console::completion::completion_input::CompletionInput; +use shirabe_external_packages::symfony::console::completion::completion_suggestions::CompletionSuggestions; +use shirabe_external_packages::symfony::console::completion::suggestion::Suggestion; +use shirabe_external_packages::symfony::console::input::input_option::InputOption as BaseInputOption; +use shirabe_php_shim::LogicException; +use shirabe_php_shim::PhpMixed; + +pub enum SuggestedValues { + List(Vec), + Closure(Box Vec>), +} + +impl std::fmt::Debug for SuggestedValues { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SuggestedValues::List(list) => write!(f, "SuggestedValues::List({:?})", list), + SuggestedValues::Closure(_) => write!(f, "SuggestedValues::Closure()"), + } + } +} + +pub enum StringOrSuggestion { + Str(String), + Suggestion(Suggestion), +} + +#[derive(Debug)] +pub struct InputOption { + inner: BaseInputOption, + suggested_values: SuggestedValues, +} + +impl InputOption { + pub fn new( + name: &str, + shortcut: Option, + mode: Option, + description: &str, + default: Option, + suggested_values: SuggestedValues, + ) -> Result { + let inner = BaseInputOption::new(name, shortcut, mode, description, default)?; + let this = Self { + inner, + suggested_values, + }; + + if let SuggestedValues::List(ref list) = this.suggested_values { + if !list.is_empty() && !this.inner.accept_value() { + return Err(LogicException { + message: "Cannot set suggested values if the option does not accept a value.".to_string(), + code: 0, + }.into()); + } + } else if let SuggestedValues::Closure(_) = this.suggested_values { + if !this.inner.accept_value() { + return Err(LogicException { + message: "Cannot set suggested values if the option does not accept a value.".to_string(), + code: 0, + }.into()); + } + } + + Ok(this) + } + + pub fn complete( + &self, + input: &CompletionInput, + suggestions: &mut CompletionSuggestions, + ) -> Result<()> { + let values: Vec = match &self.suggested_values { + SuggestedValues::List(list) => list + .iter() + .map(|s| StringOrSuggestion::Str(s.clone())) + .collect(), + SuggestedValues::Closure(closure) => closure(input, suggestions), + }; + if !values.is_empty() { + suggestions.suggest_values(values); + } + Ok(()) + } +} -- cgit v1.3.1