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