1use std::{
2 borrow::Borrow, convert::identity, convert::Infallible, ffi::OsStr, ffi::OsString, hash,
3 hash::Hash, ops::Deref, path::Path, path::PathBuf, rc::Rc, str::FromStr, sync::Arc,
4};
5
6use crate::{
7 intern::Interned,
8 mow_os_str::MowOsStr,
9 pool::{Intern, OS_STR_POOL},
10};
11
12#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
14pub struct IOsStr(Intern<OsStr>);
15
16impl IOsStr {
17 #[inline]
25 pub fn new(s: impl AsRef<OsStr>) -> Self {
26 Self(OS_STR_POOL.intern(s.as_ref(), Arc::from))
27 }
28
29 #[inline]
31 pub fn from_os_string(s: OsString) -> Self {
32 Self(OS_STR_POOL.intern(s, Arc::from))
33 }
34
35 #[inline]
37 pub fn from_boxed(s: Box<OsStr>) -> Self {
38 Self(OS_STR_POOL.intern(s, Arc::from))
39 }
40
41 #[inline]
43 pub fn from_arc(s: Arc<OsStr>) -> Self {
44 Self(OS_STR_POOL.intern(s, identity))
45 }
46
47 #[inline]
49 pub fn from_rc(s: Rc<OsStr>) -> Self {
50 Self(OS_STR_POOL.intern(s, |s| Arc::from(s.to_os_string())))
51 }
52
53 #[inline]
55 pub fn from_mow(s: MowOsStr) -> Self {
56 s.into()
57 }
58
59 #[inline]
61 pub fn from_to_arc<S: AsRef<OsStr>>(s: S, to_arc: impl FnOnce(S) -> Arc<OsStr>) -> Self {
62 Self(OS_STR_POOL.intern(s, to_arc))
63 }
64}
65
66impl IOsStr {
67 #[inline]
69 pub fn as_os_str(&self) -> &OsStr {
70 self.deref()
71 }
72
73 #[inline]
75 pub fn into_boxed_os_str(&self) -> Box<OsStr> {
76 self.deref().into()
77 }
78
79 #[inline]
81 pub fn into_mut(&self) -> MowOsStr {
82 MowOsStr::from(self.clone())
83 }
84}
85
86unsafe impl Interned for IOsStr {}
87
88impl Deref for IOsStr {
89 type Target = OsStr;
90
91 #[inline]
92 fn deref(&self) -> &Self::Target {
93 self.as_ref()
94 }
95}
96
97impl AsRef<OsStr> for IOsStr {
98 #[inline]
99 fn as_ref(&self) -> &OsStr {
100 self.0.get()
101 }
102}
103
104impl AsRef<Path> for IOsStr {
105 #[inline]
106 fn as_ref(&self) -> &Path {
107 self.deref().as_ref()
108 }
109}
110
111impl Hash for IOsStr {
112 #[inline]
113 fn hash<H: hash::Hasher>(&self, state: &mut H) {
114 self.deref().hash(state)
115 }
116}
117
118impl Borrow<OsStr> for IOsStr {
119 #[inline]
120 fn borrow(&self) -> &OsStr {
121 self.deref()
122 }
123}
124
125impl From<&'_ String> for IOsStr {
126 #[inline]
127 fn from(s: &'_ String) -> Self {
128 Self::new(s)
129 }
130}
131
132impl From<&'_ str> for IOsStr {
133 #[inline]
134 fn from(s: &'_ str) -> Self {
135 Self::new(s)
136 }
137}
138
139impl From<&'_ mut str> for IOsStr {
140 #[inline]
141 fn from(s: &'_ mut str) -> Self {
142 Self::new(s)
143 }
144}
145
146impl From<char> for IOsStr {
147 #[inline]
148 fn from(c: char) -> Self {
149 let mut tmp = [0; 4];
150 Self::new(c.encode_utf8(&mut tmp))
151 }
152}
153
154impl From<Box<OsStr>> for IOsStr {
155 #[inline]
156 fn from(s: Box<OsStr>) -> Self {
157 Self::from_boxed(s)
158 }
159}
160
161impl From<Arc<OsStr>> for IOsStr {
162 #[inline]
163 fn from(s: Arc<OsStr>) -> Self {
164 Self::from_arc(s)
165 }
166}
167
168impl From<Rc<OsStr>> for IOsStr {
169 #[inline]
170 fn from(s: Rc<OsStr>) -> Self {
171 Self::from_rc(s)
172 }
173}
174
175impl From<PathBuf> for IOsStr {
176 #[inline]
177 fn from(s: PathBuf) -> Self {
178 Self::from_os_string(s.into())
179 }
180}
181
182impl From<OsString> for IOsStr {
183 #[inline]
184 fn from(s: OsString) -> Self {
185 Self::from_os_string(s)
186 }
187}
188
189impl From<&'_ OsStr> for IOsStr {
190 #[inline]
191 fn from(s: &OsStr) -> Self {
192 Self::new(s)
193 }
194}
195
196impl From<&'_ OsString> for IOsStr {
197 #[inline]
198 fn from(s: &OsString) -> Self {
199 Self::new(s)
200 }
201}
202
203impl From<String> for IOsStr {
204 #[inline]
205 fn from(s: String) -> Self {
206 Self::from_os_string(s.into())
207 }
208}
209
210impl FromStr for IOsStr {
211 type Err = Infallible;
212
213 fn from_str(s: &str) -> Result<Self, Self::Err> {
214 OsString::from_str(s).map(Self::from_os_string)
215 }
216}
217
218impl From<IOsStr> for Box<OsStr> {
219 #[inline]
220 fn from(v: IOsStr) -> Self {
221 Self::from(v.deref())
222 }
223}
224
225impl From<IOsStr> for Arc<OsStr> {
226 #[inline]
227 fn from(v: IOsStr) -> Self {
228 v.0.into()
229 }
230}
231
232impl From<IOsStr> for Rc<OsStr> {
233 #[inline]
234 fn from(v: IOsStr) -> Self {
235 Self::from(v.deref())
236 }
237}
238
239impl From<IOsStr> for OsString {
240 #[inline]
241 fn from(v: IOsStr) -> Self {
242 Self::from(v.deref())
243 }
244}
245
246impl From<IOsStr> for PathBuf {
247 #[inline]
248 fn from(v: IOsStr) -> Self {
249 Self::from(v.deref())
250 }
251}
252
253impl PartialEq<OsStr> for IOsStr {
254 fn eq(&self, other: &OsStr) -> bool {
255 self.deref() == other
256 }
257}
258
259impl PartialEq<&OsStr> for IOsStr {
260 fn eq(&self, other: &&OsStr) -> bool {
261 self.deref() == *other
262 }
263}
264
265impl PartialEq<OsString> for IOsStr {
266 fn eq(&self, other: &OsString) -> bool {
267 self.deref() == *other
268 }
269}
270
271impl PartialEq<str> for IOsStr {
272 fn eq(&self, other: &str) -> bool {
273 self.deref() == other
274 }
275}
276
277impl PartialEq<&str> for IOsStr {
278 fn eq(&self, other: &&str) -> bool {
279 self.deref() == *other
280 }
281}
282
283impl PartialEq<String> for IOsStr {
284 fn eq(&self, other: &String) -> bool {
285 self.deref() == other.as_str()
286 }
287}