clap_builder/builder/
str.rs

1/// A UTF-8-encoded fixed string
2///
3/// **NOTE:** To support dynamic values (i.e. `String`), enable the `string`
4/// feature
5#[derive(Default, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
6pub struct Str {
7    name: Inner,
8}
9
10impl Str {
11    #[cfg(feature = "string")]
12    pub(crate) fn from_string(name: String) -> Self {
13        Self {
14            name: Inner::from_string(name),
15        }
16    }
17
18    #[cfg(feature = "string")]
19    pub(crate) fn from_ref(name: &str) -> Self {
20        Self {
21            name: Inner::from_ref(name),
22        }
23    }
24
25    pub(crate) fn from_static_ref(name: &'static str) -> Self {
26        Self {
27            name: Inner::from_static_ref(name),
28        }
29    }
30
31    pub(crate) fn into_inner(self) -> Inner {
32        self.name
33    }
34
35    /// Get the raw string of the `Str`
36    pub fn as_str(&self) -> &str {
37        self.name.as_str()
38    }
39}
40
41impl From<&'_ Str> for Str {
42    fn from(id: &'_ Str) -> Self {
43        id.clone()
44    }
45}
46
47#[cfg(feature = "string")]
48impl From<String> for Str {
49    fn from(name: String) -> Self {
50        Self::from_string(name)
51    }
52}
53
54#[cfg(feature = "string")]
55impl From<&'_ String> for Str {
56    fn from(name: &'_ String) -> Self {
57        Self::from_ref(name.as_str())
58    }
59}
60
61impl From<&'static str> for Str {
62    fn from(name: &'static str) -> Self {
63        Self::from_static_ref(name)
64    }
65}
66
67impl From<&'_ &'static str> for Str {
68    fn from(name: &'_ &'static str) -> Self {
69        Self::from_static_ref(name)
70    }
71}
72
73impl From<Str> for String {
74    fn from(name: Str) -> Self {
75        name.name.into_string()
76    }
77}
78
79impl From<Str> for Vec<u8> {
80    fn from(name: Str) -> Self {
81        String::from(name).into()
82    }
83}
84
85impl From<Str> for std::ffi::OsString {
86    fn from(name: Str) -> Self {
87        String::from(name).into()
88    }
89}
90
91impl From<Str> for std::path::PathBuf {
92    fn from(name: Str) -> Self {
93        String::from(name).into()
94    }
95}
96
97impl std::fmt::Display for Str {
98    #[inline]
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        std::fmt::Display::fmt(self.as_str(), f)
101    }
102}
103
104impl std::fmt::Debug for Str {
105    #[inline]
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        std::fmt::Debug::fmt(self.as_str(), f)
108    }
109}
110
111impl std::ops::Deref for Str {
112    type Target = str;
113
114    #[inline]
115    fn deref(&self) -> &str {
116        self.as_str()
117    }
118}
119
120impl AsRef<str> for Str {
121    #[inline]
122    fn as_ref(&self) -> &str {
123        self.as_str()
124    }
125}
126
127impl AsRef<[u8]> for Str {
128    #[inline]
129    fn as_ref(&self) -> &[u8] {
130        self.as_bytes()
131    }
132}
133
134impl AsRef<std::ffi::OsStr> for Str {
135    #[inline]
136    fn as_ref(&self) -> &std::ffi::OsStr {
137        (**self).as_ref()
138    }
139}
140
141impl AsRef<std::path::Path> for Str {
142    #[inline]
143    fn as_ref(&self) -> &std::path::Path {
144        std::path::Path::new(self)
145    }
146}
147
148impl std::borrow::Borrow<str> for Str {
149    #[inline]
150    fn borrow(&self) -> &str {
151        self.as_str()
152    }
153}
154
155impl PartialEq<str> for Str {
156    #[inline]
157    fn eq(&self, other: &str) -> bool {
158        PartialEq::eq(self.as_str(), other)
159    }
160}
161impl PartialEq<Str> for str {
162    #[inline]
163    fn eq(&self, other: &Str) -> bool {
164        PartialEq::eq(self, other.as_str())
165    }
166}
167
168impl PartialEq<&'_ str> for Str {
169    #[inline]
170    fn eq(&self, other: &&str) -> bool {
171        PartialEq::eq(self.as_str(), *other)
172    }
173}
174impl PartialEq<Str> for &'_ str {
175    #[inline]
176    fn eq(&self, other: &Str) -> bool {
177        PartialEq::eq(*self, other.as_str())
178    }
179}
180
181impl PartialEq<std::ffi::OsStr> for Str {
182    #[inline]
183    fn eq(&self, other: &std::ffi::OsStr) -> bool {
184        PartialEq::eq(self.as_str(), other)
185    }
186}
187impl PartialEq<Str> for std::ffi::OsStr {
188    #[inline]
189    fn eq(&self, other: &Str) -> bool {
190        PartialEq::eq(self, other.as_str())
191    }
192}
193
194impl PartialEq<&'_ std::ffi::OsStr> for Str {
195    #[inline]
196    fn eq(&self, other: &&std::ffi::OsStr) -> bool {
197        PartialEq::eq(self.as_str(), *other)
198    }
199}
200impl PartialEq<Str> for &'_ std::ffi::OsStr {
201    #[inline]
202    fn eq(&self, other: &Str) -> bool {
203        PartialEq::eq(*self, other.as_str())
204    }
205}
206
207impl PartialEq<String> for Str {
208    #[inline]
209    fn eq(&self, other: &String) -> bool {
210        PartialEq::eq(self.as_str(), other.as_str())
211    }
212}
213impl PartialEq<Str> for String {
214    #[inline]
215    fn eq(&self, other: &Str) -> bool {
216        PartialEq::eq(self.as_str(), other.as_str())
217    }
218}
219
220#[cfg(feature = "string")]
221pub(crate) mod inner {
222    #[derive(Clone)]
223    pub(crate) enum Inner {
224        Static(&'static str),
225        Owned(Box<str>),
226    }
227
228    impl Inner {
229        pub(crate) fn from_string(name: String) -> Self {
230            Self::Owned(name.into_boxed_str())
231        }
232
233        pub(crate) fn from_ref(name: &str) -> Self {
234            Self::Owned(Box::from(name))
235        }
236
237        pub(crate) fn from_static_ref(name: &'static str) -> Self {
238            Self::Static(name)
239        }
240
241        pub(crate) fn as_str(&self) -> &str {
242            match self {
243                Self::Static(s) => s,
244                Self::Owned(s) => s.as_ref(),
245            }
246        }
247
248        pub(crate) fn into_string(self) -> String {
249            match self {
250                Self::Static(s) => s.to_owned(),
251                Self::Owned(s) => s.into(),
252            }
253        }
254    }
255}
256
257#[cfg(not(feature = "string"))]
258pub(crate) mod inner {
259    #[derive(Clone)]
260    pub(crate) struct Inner(pub(crate) &'static str);
261
262    impl Inner {
263        pub(crate) fn from_static_ref(name: &'static str) -> Self {
264            Self(name)
265        }
266
267        pub(crate) fn as_str(&self) -> &str {
268            self.0
269        }
270
271        pub(crate) fn into_string(self) -> String {
272            self.as_str().to_owned()
273        }
274    }
275}
276
277pub(crate) use inner::Inner;
278
279impl Default for Inner {
280    fn default() -> Self {
281        Self::from_static_ref("")
282    }
283}
284
285impl PartialEq for Inner {
286    fn eq(&self, other: &Inner) -> bool {
287        self.as_str() == other.as_str()
288    }
289}
290
291impl PartialOrd for Inner {
292    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
293        Some(self.cmp(other))
294    }
295}
296
297impl Ord for Inner {
298    fn cmp(&self, other: &Inner) -> std::cmp::Ordering {
299        self.as_str().cmp(other.as_str())
300    }
301}
302
303impl Eq for Inner {}
304
305impl std::hash::Hash for Inner {
306    #[inline]
307    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
308        self.as_str().hash(state);
309    }
310}