summaryrefslogtreecommitdiff
path: root/mingling/src
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-04-07 08:56:26 +0800
committer魏曹先生 <1992414357@qq.com>2026-04-07 08:56:26 +0800
commitdacc35a768548e29487a875ad84749013ec6a7f1 (patch)
tree43a1e66792b3816b9f1cf2ce7b94a1e6e123a82e /mingling/src
parent8092d24fc44f06506d45acd9fa934b009fd07899 (diff)
Add YesOrNo and TrueOrFalse pickable boolean types
Diffstat (limited to 'mingling/src')
-rw-r--r--mingling/src/parser.rs2
-rw-r--r--mingling/src/parser/picker.rs3
-rw-r--r--mingling/src/parser/picker/bools.rs140
3 files changed, 145 insertions, 0 deletions
diff --git a/mingling/src/parser.rs b/mingling/src/parser.rs
index be6f9b2..ca3ca8c 100644
--- a/mingling/src/parser.rs
+++ b/mingling/src/parser.rs
@@ -3,3 +3,5 @@ pub use crate::parser::args::*;
mod picker;
pub use crate::parser::picker::*;
+
+pub use crate::parser::picker::bools::*;
diff --git a/mingling/src/parser/picker.rs b/mingling/src/parser/picker.rs
index 05021a7..c6c2beb 100644
--- a/mingling/src/parser/picker.rs
+++ b/mingling/src/parser/picker.rs
@@ -6,6 +6,9 @@ use mingling_core::Flag;
#[doc(hidden)]
pub mod builtin;
+#[doc(hidden)]
+pub mod bools;
+
/// A builder for extracting values from command-line arguments.
///
/// The `Picker` struct holds parsed arguments and provides a fluent interface
diff --git a/mingling/src/parser/picker/bools.rs b/mingling/src/parser/picker/bools.rs
new file mode 100644
index 0000000..f0a2622
--- /dev/null
+++ b/mingling/src/parser/picker/bools.rs
@@ -0,0 +1,140 @@
+use crate::parser::Pickable;
+
+#[derive(Debug, Default)]
+pub enum YesOrNo {
+ Yes,
+ #[default]
+ No,
+}
+
+impl From<bool> for YesOrNo {
+ fn from(b: bool) -> Self {
+ if b { YesOrNo::Yes } else { YesOrNo::No }
+ }
+}
+
+impl From<YesOrNo> for bool {
+ fn from(val: YesOrNo) -> Self {
+ match val {
+ YesOrNo::Yes => true,
+ YesOrNo::No => false,
+ }
+ }
+}
+
+impl std::ops::Deref for YesOrNo {
+ type Target = bool;
+
+ fn deref(&self) -> &Self::Target {
+ static TRUE: bool = true;
+ static FALSE: bool = false;
+ match self {
+ YesOrNo::Yes => &TRUE,
+ YesOrNo::No => &FALSE,
+ }
+ }
+}
+
+impl YesOrNo {
+ pub fn is_yes(&self) -> bool {
+ matches!(self, YesOrNo::Yes)
+ }
+
+ pub fn is_no(&self) -> bool {
+ matches!(self, YesOrNo::No)
+ }
+}
+
+impl Pickable for YesOrNo {
+ type Output = YesOrNo;
+
+ fn pick(args: &mut crate::parser::Argument, flag: mingling_core::Flag) -> Option<Self::Output> {
+ let value = pick_bool(args, flag, &["y", "yes"], &["n", "no"]);
+ Some(value.into())
+ }
+}
+
+#[derive(Debug, Default)]
+pub enum TrueOrFalse {
+ True,
+ #[default]
+ False,
+}
+
+impl From<bool> for TrueOrFalse {
+ fn from(b: bool) -> Self {
+ if b {
+ TrueOrFalse::True
+ } else {
+ TrueOrFalse::False
+ }
+ }
+}
+
+impl From<TrueOrFalse> for bool {
+ fn from(val: TrueOrFalse) -> Self {
+ match val {
+ TrueOrFalse::True => true,
+ TrueOrFalse::False => false,
+ }
+ }
+}
+
+impl std::ops::Deref for TrueOrFalse {
+ type Target = bool;
+
+ fn deref(&self) -> &Self::Target {
+ static TRUE: bool = true;
+ static FALSE: bool = false;
+ match self {
+ TrueOrFalse::True => &TRUE,
+ TrueOrFalse::False => &FALSE,
+ }
+ }
+}
+
+impl TrueOrFalse {
+ pub fn is_true(&self) -> bool {
+ matches!(self, TrueOrFalse::True)
+ }
+
+ pub fn is_false(&self) -> bool {
+ matches!(self, TrueOrFalse::False)
+ }
+}
+
+impl Pickable for TrueOrFalse {
+ type Output = TrueOrFalse;
+
+ fn pick(args: &mut crate::parser::Argument, flag: mingling_core::Flag) -> Option<Self::Output> {
+ let value = pick_bool(args, flag, &["true", "t"], &["false", "f"]);
+ Some(value.into())
+ }
+}
+
+fn pick_bool(
+ args: &mut crate::parser::Argument,
+ flag: mingling_core::Flag,
+ positive: &[&str],
+ negative: &[&str],
+) -> bool {
+ let has_flag = args.pick_flag(flag.clone());
+ if !has_flag {
+ let content = args.pick_argument(flag);
+ match content {
+ Some(content) => {
+ let s = content.as_str();
+ if positive.contains(&s) {
+ true
+ } else if negative.contains(&s) {
+ false
+ } else {
+ false
+ }
+ }
+ None => false,
+ }
+ } else {
+ true
+ }
+}