Skip to main content

clap_builder/builder/
resettable.rs

1// Unlike `impl Into<Option<T>>` or `Option<impl Into<T>>`, this isn't ambiguous for the `None`
2// case.
3
4use crate::builder::ArgAction;
5use crate::builder::OsStr;
6use crate::builder::Str;
7use crate::builder::StyledStr;
8use crate::builder::ValueHint;
9use crate::builder::ValueParser;
10use crate::builder::ValueRange;
11
12/// Clearable builder value
13///
14/// This allows a builder function to both accept any value that can [`Into::into`] `T` (like
15/// `&str` into `OsStr`) as well as `None` to reset it to the default.  This is needed to
16/// workaround a limitation where you can't have a function argument that is `impl Into<Option<T>>`
17/// where `T` is `impl Into<S>` accept `None` as its type is ambiguous.
18///
19/// # Example
20///
21/// ```rust
22/// # use clap_builder as clap;
23/// # use clap::Command;
24/// # use clap::Arg;
25/// fn common() -> Command {
26///     Command::new("cli")
27///         .arg(Arg::new("input").short('i').long("input"))
28/// }
29/// let mut command = common();
30/// command.mut_arg("input", |arg| arg.short(None));
31/// ```
32#[derive(#[automatically_derived]
impl<T: ::core::marker::Copy> ::core::marker::Copy for Resettable<T> { }Copy, #[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for Resettable<T> {
    #[inline]
    fn clone(&self) -> Resettable<T> {
        match self {
            Resettable::Value(__self_0) =>
                Resettable::Value(::core::clone::Clone::clone(__self_0)),
            Resettable::Reset => Resettable::Reset,
        }
    }
}Clone, #[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for Resettable<T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Resettable::Value(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Value",
                    &__self_0),
            Resettable::Reset =>
                ::core::fmt::Formatter::write_str(f, "Reset"),
        }
    }
}Debug, #[automatically_derived]
impl<T: ::core::cmp::PartialEq> ::core::cmp::PartialEq for Resettable<T> {
    #[inline]
    fn eq(&self, other: &Resettable<T>) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Resettable::Value(__self_0), Resettable::Value(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<T: ::core::cmp::Eq> ::core::cmp::Eq for Resettable<T> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) { let _: ::core::cmp::AssertParamIsEq<T>; }
}Eq, #[automatically_derived]
impl<T: ::core::cmp::PartialOrd> ::core::cmp::PartialOrd for Resettable<T> {
    #[inline]
    fn partial_cmp(&self, other: &Resettable<T>)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match (self, other) {
            (Resettable::Value(__self_0), Resettable::Value(__arg1_0)) =>
                ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
            _ =>
                ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
                    &__arg1_discr),
        }
    }
}PartialOrd, #[automatically_derived]
impl<T: ::core::cmp::Ord> ::core::cmp::Ord for Resettable<T> {
    #[inline]
    fn cmp(&self, other: &Resettable<T>) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
            ::core::cmp::Ordering::Equal =>
                match (self, other) {
                    (Resettable::Value(__self_0), Resettable::Value(__arg1_0))
                        => ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    _ => ::core::cmp::Ordering::Equal,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl<T: ::core::hash::Hash> ::core::hash::Hash for Resettable<T> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            Resettable::Value(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash)]
33pub enum Resettable<T> {
34    /// Overwrite builder value
35    Value(T),
36    /// Reset builder value
37    Reset,
38}
39
40impl<T> Resettable<T> {
41    pub(crate) fn into_option(self) -> Option<T> {
42        match self {
43            Self::Value(t) => Some(t),
44            Self::Reset => None,
45        }
46    }
47}
48
49impl<T> From<T> for Resettable<T> {
50    fn from(other: T) -> Self {
51        Self::Value(other)
52    }
53}
54
55impl<T> From<Option<T>> for Resettable<T> {
56    fn from(other: Option<T>) -> Self {
57        match other {
58            Some(inner) => Self::Value(inner),
59            None => Self::Reset,
60        }
61    }
62}
63
64/// Convert to the intended resettable type
65pub trait IntoResettable<T> {
66    /// Convert to the intended resettable type
67    fn into_resettable(self) -> Resettable<T>;
68}
69
70impl IntoResettable<char> for Option<char> {
71    fn into_resettable(self) -> Resettable<char> {
72        match self {
73            Some(s) => Resettable::Value(s),
74            None => Resettable::Reset,
75        }
76    }
77}
78
79impl IntoResettable<usize> for Option<usize> {
80    fn into_resettable(self) -> Resettable<usize> {
81        match self {
82            Some(s) => Resettable::Value(s),
83            None => Resettable::Reset,
84        }
85    }
86}
87
88impl IntoResettable<ArgAction> for Option<ArgAction> {
89    fn into_resettable(self) -> Resettable<ArgAction> {
90        match self {
91            Some(s) => Resettable::Value(s),
92            None => Resettable::Reset,
93        }
94    }
95}
96
97impl IntoResettable<ValueHint> for Option<ValueHint> {
98    fn into_resettable(self) -> Resettable<ValueHint> {
99        match self {
100            Some(s) => Resettable::Value(s),
101            None => Resettable::Reset,
102        }
103    }
104}
105
106impl IntoResettable<ValueParser> for Option<ValueParser> {
107    fn into_resettable(self) -> Resettable<ValueParser> {
108        match self {
109            Some(s) => Resettable::Value(s),
110            None => Resettable::Reset,
111        }
112    }
113}
114
115impl IntoResettable<StyledStr> for Option<&'static str> {
116    fn into_resettable(self) -> Resettable<StyledStr> {
117        match self {
118            Some(s) => Resettable::Value(s.into()),
119            None => Resettable::Reset,
120        }
121    }
122}
123
124impl IntoResettable<OsStr> for Option<&'static str> {
125    fn into_resettable(self) -> Resettable<OsStr> {
126        match self {
127            Some(s) => Resettable::Value(s.into()),
128            None => Resettable::Reset,
129        }
130    }
131}
132
133impl IntoResettable<Str> for Option<&'static str> {
134    fn into_resettable(self) -> Resettable<Str> {
135        match self {
136            Some(s) => Resettable::Value(s.into()),
137            None => Resettable::Reset,
138        }
139    }
140}
141
142impl<T> IntoResettable<T> for Resettable<T> {
143    fn into_resettable(self) -> Resettable<T> {
144        self
145    }
146}
147
148impl IntoResettable<char> for char {
149    fn into_resettable(self) -> Resettable<char> {
150        Resettable::Value(self)
151    }
152}
153
154impl IntoResettable<usize> for usize {
155    fn into_resettable(self) -> Resettable<usize> {
156        Resettable::Value(self)
157    }
158}
159
160impl IntoResettable<ArgAction> for ArgAction {
161    fn into_resettable(self) -> Resettable<ArgAction> {
162        Resettable::Value(self)
163    }
164}
165
166impl IntoResettable<ValueHint> for ValueHint {
167    fn into_resettable(self) -> Resettable<ValueHint> {
168        Resettable::Value(self)
169    }
170}
171
172impl<I: Into<ValueRange>> IntoResettable<ValueRange> for I {
173    fn into_resettable(self) -> Resettable<ValueRange> {
174        Resettable::Value(self.into())
175    }
176}
177
178impl<I: Into<ValueParser>> IntoResettable<ValueParser> for I {
179    fn into_resettable(self) -> Resettable<ValueParser> {
180        Resettable::Value(self.into())
181    }
182}
183
184impl<I: Into<String>> IntoResettable<String> for I {
185    fn into_resettable(self) -> Resettable<String> {
186        Resettable::Value(self.into())
187    }
188}
189
190impl<I: Into<StyledStr>> IntoResettable<StyledStr> for I {
191    fn into_resettable(self) -> Resettable<StyledStr> {
192        Resettable::Value(self.into())
193    }
194}
195
196impl<I: Into<OsStr>> IntoResettable<OsStr> for I {
197    fn into_resettable(self) -> Resettable<OsStr> {
198        Resettable::Value(self.into())
199    }
200}
201
202impl<I: Into<Str>> IntoResettable<Str> for I {
203    fn into_resettable(self) -> Resettable<Str> {
204        Resettable::Value(self.into())
205    }
206}
207
208impl<I: Into<crate::Id>> IntoResettable<crate::Id> for I {
209    fn into_resettable(self) -> Resettable<crate::Id> {
210        Resettable::Value(self.into())
211    }
212}