1use crate::{Bstr, Bytes, Result, Ustr};
2use std::{
3 borrow::Borrow,
4 convert::TryFrom,
5 ffi::{CString, OsStr, OsString},
6 fmt,
7 fmt::{Debug, Formatter},
8 mem,
9 mem::MaybeUninit,
10 ops::{Deref, DerefMut},
11 os::unix::ffi::OsStringExt,
12 path::{Path, PathBuf},
13 slice,
14};
15
16#[derive(Eq, Ord, PartialOrd, PartialEq, Hash)]
25pub struct Ustring {
26 bytes: Vec<u8>,
28}
29
30impl Ustring {
31 pub fn new() -> Ustring {
35 Ustring { bytes: Vec::new() }
36 }
37
38 fn init(&mut self) {
39 if self.bytes.is_empty() {
40 self.bytes.push(0);
41 }
42 }
43
44 pub fn reserve(&mut self, num: usize) {
48 self.init();
49 self.bytes.reserve(num);
50 }
51
52 pub fn reserve_exact(&mut self, additional: usize) {
56 self.init();
57 self.bytes.reserve_exact(additional);
58 }
59
60 pub fn capacity(&self) -> usize {
62 if self.bytes.is_empty() {
63 0
64 } else {
65 self.bytes.capacity() - 1
66 }
67 }
68
69 pub unsafe fn with_unused<F>(&mut self, f: F) -> Result<usize>
81 where
82 F: FnOnce(&mut [MaybeUninit<u8>]) -> Result<usize>,
83 {
84 let mut s = mem::replace(self, Ustring::new());
85 s.init();
86
87 let res = {
88 let bytes = slice::from_raw_parts_mut(
89 s.bytes.as_mut_ptr().add(s.bytes.len() - 1) as *mut _,
90 s.bytes.capacity() - s.bytes.len() + 1,
91 );
92 let len = bytes.len();
93 let res = f(&mut bytes[..len - 1]);
94 match res {
95 Ok(num) => {
96 bytes[num] = MaybeUninit::new(0);
97 s.bytes.set_len(s.bytes.len() + num);
98 }
99 _ => bytes[0] = MaybeUninit::new(0),
100 }
101 res
102 };
103
104 *self = s;
105 res
106 }
107
108 pub fn from_vec(mut s: Vec<u8>) -> Self {
110 if !s.is_empty() {
111 s.push(0);
112 }
113 Ustring { bytes: s }
114 }
115
116 pub unsafe fn from_vec_with_nul_unchecked(s: Vec<u8>) -> Self {
122 Ustring { bytes: s }
123 }
124
125 pub fn from_vec_with_nul(s: Vec<u8>) -> std::result::Result<Self, Vec<u8>> {
127 if !s.is_empty() && s[s.len() - 1] != 0 {
128 return Err(s);
129 }
130 Ok(Ustring { bytes: s })
131 }
132
133 pub fn into_vec(mut self) -> Vec<u8> {
135 if !self.bytes.is_empty() {
136 self.bytes.pop();
137 }
138 self.bytes
139 }
140
141 pub fn into_vec_with_nul(mut self) -> Vec<u8> {
143 self.init();
144 self.bytes
145 }
146
147 pub fn from_string(s: String) -> Self {
149 Self::from_vec(s.into_bytes())
150 }
151
152 pub fn from_string_with_nul(s: String) -> std::result::Result<Self, String> {
154 if !s.is_empty() && s.as_bytes()[s.len() - 1] != 0 {
155 return Err(s);
156 }
157 Ok(unsafe { Self::from_vec_with_nul_unchecked(s.into_bytes()) })
158 }
159
160 pub fn into_string(self) -> std::result::Result<String, Self> {
162 String::from_utf8(self.into_vec()).map_err(|e| Self::from_vec(e.into_bytes()))
163 }
164
165 pub fn into_string_with_nul(self) -> std::result::Result<String, Self> {
167 String::from_utf8(self.into_vec_with_nul())
168 .map_err(|e| Self::from_vec(e.into_bytes()))
169 }
170
171 pub fn from_c_string(s: CString) -> Self {
173 Self::from_vec(s.into_bytes())
174 }
175
176 pub fn into_c_string(self) -> std::result::Result<CString, (usize, Self)> {
180 CString::new(self.into_vec())
181 .map_err(|e| (e.nul_position(), Self::from_vec(e.into_vec())))
182 }
183
184 pub fn from_os_string(s: OsString) -> Self {
186 Self::from_vec(s.into_vec())
187 }
188
189 pub fn from_os_string_with_nul(s: OsString) -> std::result::Result<Self, OsString> {
191 Self::from_vec_with_nul(s.into_vec()).map_err(OsString::from_vec)
192 }
193
194 pub fn into_os_string(self) -> OsString {
196 OsString::from_vec(self.into_vec())
197 }
198
199 pub fn into_os_string_with_nul(self) -> OsString {
201 OsString::from_vec(self.into_vec_with_nul())
202 }
203
204 pub fn from_path_buf(s: PathBuf) -> Self {
206 Self::from_os_string(s.into_os_string())
207 }
208
209 pub fn from_path_buf_with_nul(s: PathBuf) -> std::result::Result<Self, PathBuf> {
211 Self::from_os_string_with_nul(s.into_os_string()).map_err(PathBuf::from)
212 }
213
214 pub fn into_path_buf(self) -> PathBuf {
216 PathBuf::from(self.into_os_string())
217 }
218
219 pub fn into_path_buf_with_nul(self) -> PathBuf {
221 PathBuf::from(self.into_os_string_with_nul())
222 }
223
224 pub fn push<T: Bytes + ?Sized>(&mut self, bytes: &T) {
235 let bytes = bytes.bytes();
236 if !bytes.is_empty() {
237 self.init();
238 self.bytes.reserve(bytes.len());
239 self.bytes.pop();
240 self.bytes.extend_from_slice(bytes);
241 self.bytes.push(0);
242 }
243 }
244
245 pub fn as_ustr(&self) -> &Ustr {
247 if self.bytes.is_empty() {
248 Ustr::empty()
249 } else {
250 unsafe { Ustr::from_bytes_unchecked(&self.bytes) }
251 }
252 }
253
254 pub fn as_ustr_mut(&mut self) -> &mut Ustr {
256 self.init();
257 unsafe { Ustr::from_bytes_unchecked_mut(&mut self.bytes) }
258 }
259}
260
261impl Default for Ustring {
262 fn default() -> Self {
263 Self::new()
264 }
265}
266
267impl Borrow<Ustr> for Ustring {
268 fn borrow(&self) -> &Ustr {
269 self.as_ustr()
270 }
271}
272
273impl Borrow<Bstr> for Ustring {
274 fn borrow(&self) -> &Bstr {
275 self.as_ustr().as_bstr()
276 }
277}
278
279impl From<String> for Ustring {
280 fn from(s: String) -> Self {
281 Ustring::from_string(s)
282 }
283}
284
285impl From<Vec<u8>> for Ustring {
286 fn from(s: Vec<u8>) -> Self {
287 Ustring::from_vec(s)
288 }
289}
290
291impl From<CString> for Ustring {
292 fn from(s: CString) -> Self {
293 Ustring::from_c_string(s)
294 }
295}
296
297impl From<OsString> for Ustring {
298 fn from(s: OsString) -> Self {
299 Ustring::from_os_string(s)
300 }
301}
302
303impl From<PathBuf> for Ustring {
304 fn from(s: PathBuf) -> Self {
305 Ustring::from_path_buf(s)
306 }
307}
308
309impl TryFrom<Ustring> for String {
310 type Error = Ustring;
311
312 fn try_from(value: Ustring) -> std::result::Result<Self, Self::Error> {
313 Ustring::into_string(value)
314 }
315}
316
317impl From<Ustring> for Vec<u8> {
318 fn from(s: Ustring) -> Self {
319 s.into_vec()
320 }
321}
322
323impl TryFrom<Ustring> for CString {
324 type Error = (usize, Ustring);
325
326 fn try_from(s: Ustring) -> std::result::Result<Self, Self::Error> {
327 s.into_c_string()
328 }
329}
330
331impl From<Ustring> for OsString {
332 fn from(s: Ustring) -> Self {
333 s.into_os_string()
334 }
335}
336
337impl From<Ustring> for PathBuf {
338 fn from(s: Ustring) -> Self {
339 s.into_path_buf()
340 }
341}
342
343impl AsRef<[u8]> for Ustring {
344 fn as_ref(&self) -> &[u8] {
345 self.deref().as_ref()
346 }
347}
348
349impl AsMut<[u8]> for Ustring {
350 fn as_mut(&mut self) -> &mut [u8] {
351 self.deref_mut().as_mut()
352 }
353}
354
355impl AsRef<OsStr> for Ustring {
356 fn as_ref(&self) -> &OsStr {
357 self.deref().as_ref()
358 }
359}
360
361impl AsRef<Path> for Ustring {
362 fn as_ref(&self) -> &Path {
363 self.deref().as_ref()
364 }
365}
366
367impl Deref for Ustring {
368 type Target = Ustr;
369
370 fn deref(&self) -> &Self::Target {
371 self.as_ustr()
372 }
373}
374
375impl DerefMut for Ustring {
376 fn deref_mut(&mut self) -> &mut Self::Target {
377 self.as_ustr_mut()
378 }
379}
380
381impl Debug for Ustring {
382 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
383 Debug::fmt(self.deref(), f)
384 }
385}