| 1 | // Unlike `impl Into<Option<T>>` or `Option<impl Into<T>>`, this isn't ambiguous for the `None` | 
| 2 | // case. | 
|---|
| 3 |  | 
|---|
| 4 | use crate::builder::ArgAction; | 
|---|
| 5 | use crate::builder::OsStr; | 
|---|
| 6 | use crate::builder::Str; | 
|---|
| 7 | use crate::builder::StyledStr; | 
|---|
| 8 | use crate::builder::ValueHint; | 
|---|
| 9 | use crate::builder::ValueParser; | 
|---|
| 10 | use 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(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | 
|---|
| 33 | pub enum Resettable<T> { | 
|---|
| 34 | /// Overwrite builder value | 
|---|
| 35 | Value(T), | 
|---|
| 36 | /// Reset builder value | 
|---|
| 37 | Reset, | 
|---|
| 38 | } | 
|---|
| 39 |  | 
|---|
| 40 | impl<T> Resettable<T> { | 
|---|
| 41 | pub(crate) fn into_option(self) -> Option<T> { | 
|---|
| 42 | match self { | 
|---|
| 43 | Self::Value(t: T) => Some(t), | 
|---|
| 44 | Self::Reset => None, | 
|---|
| 45 | } | 
|---|
| 46 | } | 
|---|
| 47 | } | 
|---|
| 48 |  | 
|---|
| 49 | impl<T> From<T> for Resettable<T> { | 
|---|
| 50 | fn from(other: T) -> Self { | 
|---|
| 51 | Self::Value(other) | 
|---|
| 52 | } | 
|---|
| 53 | } | 
|---|
| 54 |  | 
|---|
| 55 | impl<T> From<Option<T>> for Resettable<T> { | 
|---|
| 56 | fn from(other: Option<T>) -> Self { | 
|---|
| 57 | match other { | 
|---|
| 58 | Some(inner: T) => Self::Value(inner), | 
|---|
| 59 | None => Self::Reset, | 
|---|
| 60 | } | 
|---|
| 61 | } | 
|---|
| 62 | } | 
|---|
| 63 |  | 
|---|
| 64 | /// Convert to the intended resettable type | 
|---|
| 65 | pub trait IntoResettable<T> { | 
|---|
| 66 | /// Convert to the intended resettable type | 
|---|
| 67 | fn into_resettable(self) -> Resettable<T>; | 
|---|
| 68 | } | 
|---|
| 69 |  | 
|---|
| 70 | impl IntoResettable<char> for Option<char> { | 
|---|
| 71 | fn into_resettable(self) -> Resettable<char> { | 
|---|
| 72 | match self { | 
|---|
| 73 | Some(s: char) => Resettable::Value(s), | 
|---|
| 74 | None => Resettable::Reset, | 
|---|
| 75 | } | 
|---|
| 76 | } | 
|---|
| 77 | } | 
|---|
| 78 |  | 
|---|
| 79 | impl IntoResettable<usize> for Option<usize> { | 
|---|
| 80 | fn into_resettable(self) -> Resettable<usize> { | 
|---|
| 81 | match self { | 
|---|
| 82 | Some(s: usize) => Resettable::Value(s), | 
|---|
| 83 | None => Resettable::Reset, | 
|---|
| 84 | } | 
|---|
| 85 | } | 
|---|
| 86 | } | 
|---|
| 87 |  | 
|---|
| 88 | impl IntoResettable<ArgAction> for Option<ArgAction> { | 
|---|
| 89 | fn into_resettable(self) -> Resettable<ArgAction> { | 
|---|
| 90 | match self { | 
|---|
| 91 | Some(s: ArgAction) => Resettable::Value(s), | 
|---|
| 92 | None => Resettable::Reset, | 
|---|
| 93 | } | 
|---|
| 94 | } | 
|---|
| 95 | } | 
|---|
| 96 |  | 
|---|
| 97 | impl IntoResettable<ValueHint> for Option<ValueHint> { | 
|---|
| 98 | fn into_resettable(self) -> Resettable<ValueHint> { | 
|---|
| 99 | match self { | 
|---|
| 100 | Some(s: ValueHint) => Resettable::Value(s), | 
|---|
| 101 | None => Resettable::Reset, | 
|---|
| 102 | } | 
|---|
| 103 | } | 
|---|
| 104 | } | 
|---|
| 105 |  | 
|---|
| 106 | impl IntoResettable<ValueParser> for Option<ValueParser> { | 
|---|
| 107 | fn into_resettable(self) -> Resettable<ValueParser> { | 
|---|
| 108 | match self { | 
|---|
| 109 | Some(s: ValueParser) => Resettable::Value(s), | 
|---|
| 110 | None => Resettable::Reset, | 
|---|
| 111 | } | 
|---|
| 112 | } | 
|---|
| 113 | } | 
|---|
| 114 |  | 
|---|
| 115 | impl IntoResettable<StyledStr> for Option<&'static str> { | 
|---|
| 116 | fn into_resettable(self) -> Resettable<StyledStr> { | 
|---|
| 117 | match self { | 
|---|
| 118 | Some(s: &'static str) => Resettable::Value(s.into()), | 
|---|
| 119 | None => Resettable::Reset, | 
|---|
| 120 | } | 
|---|
| 121 | } | 
|---|
| 122 | } | 
|---|
| 123 |  | 
|---|
| 124 | impl IntoResettable<OsStr> for Option<&'static str> { | 
|---|
| 125 | fn into_resettable(self) -> Resettable<OsStr> { | 
|---|
| 126 | match self { | 
|---|
| 127 | Some(s: &'static str) => Resettable::Value(s.into()), | 
|---|
| 128 | None => Resettable::Reset, | 
|---|
| 129 | } | 
|---|
| 130 | } | 
|---|
| 131 | } | 
|---|
| 132 |  | 
|---|
| 133 | impl IntoResettable<Str> for Option<&'static str> { | 
|---|
| 134 | fn into_resettable(self) -> Resettable<Str> { | 
|---|
| 135 | match self { | 
|---|
| 136 | Some(s: &'static str) => Resettable::Value(s.into()), | 
|---|
| 137 | None => Resettable::Reset, | 
|---|
| 138 | } | 
|---|
| 139 | } | 
|---|
| 140 | } | 
|---|
| 141 |  | 
|---|
| 142 | impl<T> IntoResettable<T> for Resettable<T> { | 
|---|
| 143 | fn into_resettable(self) -> Resettable<T> { | 
|---|
| 144 | self | 
|---|
| 145 | } | 
|---|
| 146 | } | 
|---|
| 147 |  | 
|---|
| 148 | impl IntoResettable<char> for char { | 
|---|
| 149 | fn into_resettable(self) -> Resettable<char> { | 
|---|
| 150 | Resettable::Value(self) | 
|---|
| 151 | } | 
|---|
| 152 | } | 
|---|
| 153 |  | 
|---|
| 154 | impl IntoResettable<usize> for usize { | 
|---|
| 155 | fn into_resettable(self) -> Resettable<usize> { | 
|---|
| 156 | Resettable::Value(self) | 
|---|
| 157 | } | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 | impl IntoResettable<ArgAction> for ArgAction { | 
|---|
| 161 | fn into_resettable(self) -> Resettable<ArgAction> { | 
|---|
| 162 | Resettable::Value(self) | 
|---|
| 163 | } | 
|---|
| 164 | } | 
|---|
| 165 |  | 
|---|
| 166 | impl IntoResettable<ValueHint> for ValueHint { | 
|---|
| 167 | fn into_resettable(self) -> Resettable<ValueHint> { | 
|---|
| 168 | Resettable::Value(self) | 
|---|
| 169 | } | 
|---|
| 170 | } | 
|---|
| 171 |  | 
|---|
| 172 | impl<I: Into<ValueRange>> IntoResettable<ValueRange> for I { | 
|---|
| 173 | fn into_resettable(self) -> Resettable<ValueRange> { | 
|---|
| 174 | Resettable::Value(self.into()) | 
|---|
| 175 | } | 
|---|
| 176 | } | 
|---|
| 177 |  | 
|---|
| 178 | impl<I: Into<ValueParser>> IntoResettable<ValueParser> for I { | 
|---|
| 179 | fn into_resettable(self) -> Resettable<ValueParser> { | 
|---|
| 180 | Resettable::Value(self.into()) | 
|---|
| 181 | } | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | impl<I: Into<String>> IntoResettable<String> for I { | 
|---|
| 185 | fn into_resettable(self) -> Resettable<String> { | 
|---|
| 186 | Resettable::Value(self.into()) | 
|---|
| 187 | } | 
|---|
| 188 | } | 
|---|
| 189 |  | 
|---|
| 190 | impl<I: Into<StyledStr>> IntoResettable<StyledStr> for I { | 
|---|
| 191 | fn into_resettable(self) -> Resettable<StyledStr> { | 
|---|
| 192 | Resettable::Value(self.into()) | 
|---|
| 193 | } | 
|---|
| 194 | } | 
|---|
| 195 |  | 
|---|
| 196 | impl<I: Into<OsStr>> IntoResettable<OsStr> for I { | 
|---|
| 197 | fn into_resettable(self) -> Resettable<OsStr> { | 
|---|
| 198 | Resettable::Value(self.into()) | 
|---|
| 199 | } | 
|---|
| 200 | } | 
|---|
| 201 |  | 
|---|
| 202 | impl<I: Into<Str>> IntoResettable<Str> for I { | 
|---|
| 203 | fn into_resettable(self) -> Resettable<Str> { | 
|---|
| 204 | Resettable::Value(self.into()) | 
|---|
| 205 | } | 
|---|
| 206 | } | 
|---|
| 207 |  | 
|---|
| 208 | impl<I: Into<crate::Id>> IntoResettable<crate::Id> for I { | 
|---|
| 209 | fn into_resettable(self) -> Resettable<crate::Id> { | 
|---|
| 210 | Resettable::Value(self.into()) | 
|---|
| 211 | } | 
|---|
| 212 | } | 
|---|
| 213 |  | 
|---|