aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/io
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-05 01:50:16 +0900
committernsfisis <nsfisis@gmail.com>2026-06-05 01:50:16 +0900
commitbbb2f9454b6580fcbd337ced61b5a1888d52ce8d (patch)
tree45563449df57f63ae4a4d010a3e8e6007518c35b /crates/shirabe/src/io
parentadf14510b00929aaee85ccb8dedf9164878a0164 (diff)
downloadphp-shirabe-bbb2f9454b6580fcbd337ced61b5a1888d52ce8d.tar.gz
php-shirabe-bbb2f9454b6580fcbd337ced61b5a1888d52ce8d.tar.zst
php-shirabe-bbb2f9454b6580fcbd337ced61b5a1888d52ce8d.zip
refactor(io): model ask_and_validate validators with anyhow::Result
PHP's askAndValidate throws when a validator rejects input. Change the IOInterface validator callback and return type to anyhow::Result so the call sites can return Err instead of panic, faithfully modeling the throw semantics already supported by the Question layer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/io')
-rw-r--r--crates/shirabe/src/io/buffer_io.rs4
-rw-r--r--crates/shirabe/src/io/console_io.rs13
-rw-r--r--crates/shirabe/src/io/io_interface.rs8
-rw-r--r--crates/shirabe/src/io/null_io.rs6
4 files changed, 14 insertions, 17 deletions
diff --git a/crates/shirabe/src/io/buffer_io.rs b/crates/shirabe/src/io/buffer_io.rs
index 291b64b..836fd95 100644
--- a/crates/shirabe/src/io/buffer_io.rs
+++ b/crates/shirabe/src/io/buffer_io.rs
@@ -175,10 +175,10 @@ impl crate::io::IOInterfaceImmutable for BufferIO {
fn ask_and_validate(
&self,
question: String,
- validator: Box<dyn Fn(PhpMixed) -> PhpMixed>,
+ validator: Box<dyn Fn(PhpMixed) -> anyhow::Result<PhpMixed>>,
attempts: Option<i64>,
default: PhpMixed,
- ) -> PhpMixed {
+ ) -> anyhow::Result<PhpMixed> {
self.inner
.ask_and_validate(question, validator, attempts, default)
}
diff --git a/crates/shirabe/src/io/console_io.rs b/crates/shirabe/src/io/console_io.rs
index b69b68b..44e5609 100644
--- a/crates/shirabe/src/io/console_io.rs
+++ b/crates/shirabe/src/io/console_io.rs
@@ -487,10 +487,10 @@ impl IOInterfaceImmutable for ConsoleIO {
fn ask_and_validate(
&self,
question: String,
- validator: Box<dyn Fn(PhpMixed) -> PhpMixed>,
+ validator: Box<dyn Fn(PhpMixed) -> anyhow::Result<PhpMixed>>,
attempts: Option<i64>,
default: PhpMixed,
- ) -> PhpMixed {
+ ) -> anyhow::Result<PhpMixed> {
let _helper = self.helper_set.get("question");
let sanitized_question = Self::sanitize(PhpMixed::String(question), true)
.as_string()
@@ -502,13 +502,10 @@ impl IOInterfaceImmutable for ConsoleIO {
Some(default)
};
let mut question = Question::new(&sanitized_question, sanitized_default);
- // TODO(phase-b): IOInterface validator type is Box<dyn Fn(PhpMixed) -> PhpMixed>
- // but Question::set_validator expects Option<Box<dyn Fn(Option<PhpMixed>) -> Result<PhpMixed>>>.
- // Bridge the signatures by adapting the input/output types.
+ // Question::set_validator takes Fn(Option<PhpMixed>) -> Result<PhpMixed>; adapt the
+ // None answer to PHP's null and forward the validator's Result unchanged.
let adapted: Box<dyn Fn(Option<PhpMixed>) -> anyhow::Result<PhpMixed>> =
- Box::new(move |answer: Option<PhpMixed>| {
- Ok(validator(answer.unwrap_or(PhpMixed::Null)))
- });
+ Box::new(move |answer: Option<PhpMixed>| validator(answer.unwrap_or(PhpMixed::Null)));
question.set_validator(Some(adapted));
question.set_max_attempts(attempts);
diff --git a/crates/shirabe/src/io/io_interface.rs b/crates/shirabe/src/io/io_interface.rs
index e48f9ce..e33cea2 100644
--- a/crates/shirabe/src/io/io_interface.rs
+++ b/crates/shirabe/src/io/io_interface.rs
@@ -101,10 +101,10 @@ pub trait IOInterfaceImmutable: std::fmt::Debug {
fn ask_and_validate(
&self,
question: String,
- validator: Box<dyn Fn(PhpMixed) -> PhpMixed>,
+ validator: Box<dyn Fn(PhpMixed) -> anyhow::Result<PhpMixed>>,
attempts: Option<i64>,
default: PhpMixed,
- ) -> PhpMixed;
+ ) -> anyhow::Result<PhpMixed>;
fn ask_and_hide_answer(&self, question: String) -> Option<String>;
@@ -279,10 +279,10 @@ impl IOInterfaceImmutable for Rc<RefCell<dyn IOInterface>> {
fn ask_and_validate(
&self,
question: String,
- validator: Box<dyn Fn(PhpMixed) -> PhpMixed>,
+ validator: Box<dyn Fn(PhpMixed) -> anyhow::Result<PhpMixed>>,
attempts: Option<i64>,
default: PhpMixed,
- ) -> PhpMixed {
+ ) -> anyhow::Result<PhpMixed> {
self.borrow()
.ask_and_validate(question, validator, attempts, default)
}
diff --git a/crates/shirabe/src/io/null_io.rs b/crates/shirabe/src/io/null_io.rs
index 85a5fa5..0a83bff 100644
--- a/crates/shirabe/src/io/null_io.rs
+++ b/crates/shirabe/src/io/null_io.rs
@@ -70,11 +70,11 @@ impl IOInterfaceImmutable for NullIO {
fn ask_and_validate(
&self,
_question: String,
- _validator: Box<dyn Fn(PhpMixed) -> PhpMixed>,
+ _validator: Box<dyn Fn(PhpMixed) -> anyhow::Result<PhpMixed>>,
_attempts: Option<i64>,
default: PhpMixed,
- ) -> PhpMixed {
- default
+ ) -> anyhow::Result<PhpMixed> {
+ Ok(default)
}
fn ask_and_hide_answer(&self, _question: String) -> Option<String> {