summaryrefslogtreecommitdiffstats
path: root/third_party/rust/clap_builder/src/builder/resettable.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/clap_builder/src/builder/resettable.rs212
1 files changed, 212 insertions, 0 deletions
diff --git a/third_party/rust/clap_builder/src/builder/resettable.rs b/third_party/rust/clap_builder/src/builder/resettable.rs
new file mode 100644
index 0000000000..057274012c
--- /dev/null
+++ b/third_party/rust/clap_builder/src/builder/resettable.rs
@@ -0,0 +1,212 @@
+// Unlike `impl Into<Option<T>>` or `Option<impl Into<T>>`, this isn't ambiguous for the `None`
+// case.
+
+use crate::builder::ArgAction;
+use crate::builder::OsStr;
+use crate::builder::Str;
+use crate::builder::StyledStr;
+use crate::builder::ValueHint;
+use crate::builder::ValueParser;
+use crate::builder::ValueRange;
+
+/// Clearable builder value
+///
+/// This allows a builder function to both accept any value that can [`Into::into`] `T` (like
+/// `&str` into `OsStr`) as well as `None` to reset it to the default. This is needed to
+/// workaround a limitation where you can't have a function argument that is `impl Into<Option<T>>`
+/// where `T` is `impl Into<S>` accept `None` as its type is ambiguous.
+///
+/// # Example
+///
+/// ```rust
+/// # use clap_builder as clap;
+/// # use clap::Command;
+/// # use clap::Arg;
+/// fn common() -> Command {
+/// Command::new("cli")
+/// .arg(Arg::new("input").short('i').long("input"))
+/// }
+/// let mut command = common();
+/// command.mut_arg("input", |arg| arg.short(None));
+/// ```
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum Resettable<T> {
+ /// Overwrite builder value
+ Value(T),
+ /// Reset builder value
+ Reset,
+}
+
+impl<T> Resettable<T> {
+ pub(crate) fn into_option(self) -> Option<T> {
+ match self {
+ Self::Value(t) => Some(t),
+ Self::Reset => None,
+ }
+ }
+}
+
+impl<T> From<T> for Resettable<T> {
+ fn from(other: T) -> Self {
+ Self::Value(other)
+ }
+}
+
+impl<T> From<Option<T>> for Resettable<T> {
+ fn from(other: Option<T>) -> Self {
+ match other {
+ Some(inner) => Self::Value(inner),
+ None => Self::Reset,
+ }
+ }
+}
+
+/// Convert to the intended resettable type
+pub trait IntoResettable<T> {
+ /// Convert to the intended resettable type
+ fn into_resettable(self) -> Resettable<T>;
+}
+
+impl IntoResettable<char> for Option<char> {
+ fn into_resettable(self) -> Resettable<char> {
+ match self {
+ Some(s) => Resettable::Value(s),
+ None => Resettable::Reset,
+ }
+ }
+}
+
+impl IntoResettable<usize> for Option<usize> {
+ fn into_resettable(self) -> Resettable<usize> {
+ match self {
+ Some(s) => Resettable::Value(s),
+ None => Resettable::Reset,
+ }
+ }
+}
+
+impl IntoResettable<ArgAction> for Option<ArgAction> {
+ fn into_resettable(self) -> Resettable<ArgAction> {
+ match self {
+ Some(s) => Resettable::Value(s),
+ None => Resettable::Reset,
+ }
+ }
+}
+
+impl IntoResettable<ValueHint> for Option<ValueHint> {
+ fn into_resettable(self) -> Resettable<ValueHint> {
+ match self {
+ Some(s) => Resettable::Value(s),
+ None => Resettable::Reset,
+ }
+ }
+}
+
+impl IntoResettable<ValueParser> for Option<ValueParser> {
+ fn into_resettable(self) -> Resettable<ValueParser> {
+ match self {
+ Some(s) => Resettable::Value(s),
+ None => Resettable::Reset,
+ }
+ }
+}
+
+impl IntoResettable<StyledStr> for Option<&'static str> {
+ fn into_resettable(self) -> Resettable<StyledStr> {
+ match self {
+ Some(s) => Resettable::Value(s.into()),
+ None => Resettable::Reset,
+ }
+ }
+}
+
+impl IntoResettable<OsStr> for Option<&'static str> {
+ fn into_resettable(self) -> Resettable<OsStr> {
+ match self {
+ Some(s) => Resettable::Value(s.into()),
+ None => Resettable::Reset,
+ }
+ }
+}
+
+impl IntoResettable<Str> for Option<&'static str> {
+ fn into_resettable(self) -> Resettable<Str> {
+ match self {
+ Some(s) => Resettable::Value(s.into()),
+ None => Resettable::Reset,
+ }
+ }
+}
+
+impl<T> IntoResettable<T> for Resettable<T> {
+ fn into_resettable(self) -> Resettable<T> {
+ self
+ }
+}
+
+impl IntoResettable<char> for char {
+ fn into_resettable(self) -> Resettable<char> {
+ Resettable::Value(self)
+ }
+}
+
+impl IntoResettable<usize> for usize {
+ fn into_resettable(self) -> Resettable<usize> {
+ Resettable::Value(self)
+ }
+}
+
+impl IntoResettable<ArgAction> for ArgAction {
+ fn into_resettable(self) -> Resettable<ArgAction> {
+ Resettable::Value(self)
+ }
+}
+
+impl IntoResettable<ValueHint> for ValueHint {
+ fn into_resettable(self) -> Resettable<ValueHint> {
+ Resettable::Value(self)
+ }
+}
+
+impl<I: Into<ValueRange>> IntoResettable<ValueRange> for I {
+ fn into_resettable(self) -> Resettable<ValueRange> {
+ Resettable::Value(self.into())
+ }
+}
+
+impl<I: Into<ValueParser>> IntoResettable<ValueParser> for I {
+ fn into_resettable(self) -> Resettable<ValueParser> {
+ Resettable::Value(self.into())
+ }
+}
+
+impl<I: Into<String>> IntoResettable<String> for I {
+ fn into_resettable(self) -> Resettable<String> {
+ Resettable::Value(self.into())
+ }
+}
+
+impl<I: Into<StyledStr>> IntoResettable<StyledStr> for I {
+ fn into_resettable(self) -> Resettable<StyledStr> {
+ Resettable::Value(self.into())
+ }
+}
+
+impl<I: Into<OsStr>> IntoResettable<OsStr> for I {
+ fn into_resettable(self) -> Resettable<OsStr> {
+ Resettable::Value(self.into())
+ }
+}
+
+impl<I: Into<Str>> IntoResettable<Str> for I {
+ fn into_resettable(self) -> Resettable<Str> {
+ Resettable::Value(self.into())
+ }
+}
+
+impl<I: Into<crate::Id>> IntoResettable<crate::Id> for I {
+ fn into_resettable(self) -> Resettable<crate::Id> {
+ Resettable::Value(self.into())
+ }
+}