Skip to main content

pstr/
i_os_str.rs

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/// Immutable Interning OsString
13#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
14pub struct IOsStr(Intern<OsStr>);
15
16impl IOsStr {
17    /// Create a `IOsStr` from str slice  
18    ///
19    /// # Example
20    /// ```
21    /// # use pstr::ffi::IOsStr;
22    /// let s = IOsStr::new("hello world");
23    /// ```
24    #[inline]
25    pub fn new(s: impl AsRef<OsStr>) -> Self {
26        Self(OS_STR_POOL.intern(s.as_ref(), Arc::from))
27    }
28
29    /// Create a `IOsStr` from `OsString`  
30    #[inline]
31    pub fn from_os_string(s: OsString) -> Self {
32        Self(OS_STR_POOL.intern(s, Arc::from))
33    }
34
35    /// Create a `IOsStr` from `Box<OsStr>`  
36    #[inline]
37    pub fn from_boxed(s: Box<OsStr>) -> Self {
38        Self(OS_STR_POOL.intern(s, Arc::from))
39    }
40
41    /// Create a `IOsStr` from `Arc<OsStr>`  
42    #[inline]
43    pub fn from_arc(s: Arc<OsStr>) -> Self {
44        Self(OS_STR_POOL.intern(s, identity))
45    }
46
47    /// Create a `IOsStr` from `Rc<OsStr>`  
48    #[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    /// Create a `IOsStr` from `MowOsStr`
54    #[inline]
55    pub fn from_mow(s: MowOsStr) -> Self {
56        s.into()
57    }
58
59    /// Create a `IOsStr` from custom fn  
60    #[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    /// Converts to an `OsStr` slice.
68    #[inline]
69    pub fn as_os_str(&self) -> &OsStr {
70        self.deref()
71    }
72
73    /// Converts to an `Box<OsStr>`.
74    #[inline]
75    pub fn into_boxed_os_str(&self) -> Box<OsStr> {
76        self.deref().into()
77    }
78
79    /// Convert to `MowStr`
80    #[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}