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