From 4856f05e870ec5d2daaa74bf9a86a1519a813614 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Tue, 18 Aug 2026 08:37:30 +0900 Subject: fix(input): return a bool|string|string[]|null enum from get_option `InputInterface::get_option` returned `PhpMixed`, so the negation branch of `Input::get_option` reproduced PHP's `return !$value;` as `!value.as_bool().unwrap_or(false)`, which inverts the result for a string value instead of leaving it `false`. It now returns `InputOptionValue`, whose `to_bool` is PHP's truthiness cast. The narrowing also removes the `Vec` element handling the commands carried for array options: `as_array` hands back `&[String]`, so the `filter_map(|v| v.as_string())` chains at eight call sites collapse. Its other accessors keep `PhpMixed`'s names and meanings (`is_null`, `as_bool`, `as_string`, `to_bool`), and `From for PhpMixed` covers the callers that feed the value back into an `IndexMap` or a `PhpMixed` parameter. `Input` keeps its parsed options and `InputOption` its defaults as `PhpMixed`, so `Input::get_option` is where the narrowing happens and where a value outside the domain panics. Co-Authored-By: Claude Opus 5 (1M context) --- crates/shirabe-symfony-console/src/input/input.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'crates/shirabe-symfony-console/src/input/input.rs') diff --git a/crates/shirabe-symfony-console/src/input/input.rs b/crates/shirabe-symfony-console/src/input/input.rs index 88bb9f94..795e9c81 100644 --- a/crates/shirabe-symfony-console/src/input/input.rs +++ b/crates/shirabe-symfony-console/src/input/input.rs @@ -3,6 +3,7 @@ use crate::exception::InvalidArgumentException; use crate::exception::RuntimeException; use crate::input::InputDefinition; +use crate::input::InputOptionValue; use indexmap::IndexMap; use shirabe_php_shim::{PhpMixed, PhpResource, php_regex, preg_is_match}; @@ -156,14 +157,14 @@ impl Input { ) } - pub fn get_option(&self, name: &str) -> anyhow::Result { + pub fn get_option(&self, name: &str) -> anyhow::Result { if self.definition.has_negation(name) { let value = self.get_option(&self.definition.negation_to_name(name)?)?; - if matches!(value, PhpMixed::Null) { + if value.is_null() { return Ok(value); } - return Ok(PhpMixed::Bool(!value.as_bool().unwrap_or(false))); + return Ok(InputOptionValue::Bool(!value.to_bool())); } if !self.definition.has_option(name) { @@ -174,10 +175,11 @@ impl Input { .into()); } - Ok(if self.options.contains_key(name) { - self.options[name].clone() + Ok(if let Some(value) = self.options.get(name) { + InputOptionValue::from_php_mixed(value) } else { - self.definition.get_option(name)?.get_default().clone() + let option = self.definition.get_option(name)?; + InputOptionValue::from_php_mixed(option.get_default()) }) } -- cgit v1.3.1-4-g156e