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