aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/question
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/question')
-rw-r--r--crates/shirabe/src/question/strict_confirmation_question.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/crates/shirabe/src/question/strict_confirmation_question.rs b/crates/shirabe/src/question/strict_confirmation_question.rs
index ae1b77a..cfa9c36 100644
--- a/crates/shirabe/src/question/strict_confirmation_question.rs
+++ b/crates/shirabe/src/question/strict_confirmation_question.rs
@@ -1 +1,70 @@
//! ref: composer/src/Composer/Question/StrictConfirmationQuestion.php
+
+use anyhow::Result;
+use shirabe_external_packages::composer::pcre::preg::Preg;
+use shirabe_external_packages::symfony::console::exception::invalid_argument_exception::InvalidArgumentException;
+use shirabe_external_packages::symfony::console::question::question::Question;
+use shirabe_php_shim::{empty, is_bool, PhpMixed};
+
+pub struct StrictConfirmationQuestion {
+ inner: Question,
+ true_answer_regex: String,
+ false_answer_regex: String,
+}
+
+impl StrictConfirmationQuestion {
+ pub fn new(
+ question: String,
+ default: bool,
+ true_answer_regex: String,
+ false_answer_regex: String,
+ ) -> Self {
+ let inner = Question::new(question, PhpMixed::Bool(default));
+ let mut this = Self {
+ inner,
+ true_answer_regex,
+ false_answer_regex,
+ };
+ let normalizer = this.get_default_normalizer();
+ let validator = this.get_default_validator();
+ this.inner.set_normalizer(normalizer);
+ this.inner.set_validator(validator);
+ this
+ }
+
+ fn get_default_normalizer(&self) -> Box<dyn Fn(&PhpMixed) -> PhpMixed> {
+ let default = self.inner.get_default();
+ let true_regex = self.true_answer_regex.clone();
+ let false_regex = self.false_answer_regex.clone();
+
+ Box::new(move |answer: &PhpMixed| {
+ if is_bool(answer) {
+ return answer.clone();
+ }
+ if empty(answer) && !empty(&default) {
+ return default.clone();
+ }
+ if let PhpMixed::String(s) = answer {
+ if Preg::is_match(&true_regex, s) {
+ return PhpMixed::Bool(true);
+ }
+ if Preg::is_match(&false_regex, s) {
+ return PhpMixed::Bool(false);
+ }
+ }
+ PhpMixed::Null
+ })
+ }
+
+ fn get_default_validator(&self) -> Box<dyn Fn(&PhpMixed) -> Result<PhpMixed>> {
+ Box::new(|answer: &PhpMixed| {
+ if !is_bool(answer) {
+ return Err(InvalidArgumentException {
+ message: "Please answer yes, y, no, or n.".to_string(),
+ code: 0,
+ }.into());
+ }
+ Ok(answer.clone())
+ })
+ }
+}