Skip to main content

bstr/
ext_vec.rs

1use core::{fmt, iter, ops, ptr};
2
3use alloc::{borrow::Cow, string::String, vec, vec::Vec};
4
5#[cfg(feature = "std")]
6use std::{
7    error,
8    ffi::{OsStr, OsString},
9    path::{Path, PathBuf},
10};
11
12use crate::{
13    ext_slice::ByteSlice,
14    utf8::{self, Utf8Error},
15    BString,
16};
17
18/// Concatenate the elements given by the iterator together into a single
19/// `Vec<u8>`.
20///
21/// The elements may be any type that can be cheaply converted into an `&[u8]`.
22/// This includes, but is not limited to, `&str`, `&BStr` and `&[u8]` itself.
23///
24/// # Examples
25///
26/// Basic usage:
27///
28/// ```
29/// use bstr;
30///
31/// let s = bstr::concat(&["foo", "bar", "baz"]);
32/// assert_eq!(s, "foobarbaz".as_bytes());
33/// ```
34#[inline]
35pub fn concat<T, I>(elements: I) -> Vec<u8>
36where
37    T: AsRef<[u8]>,
38    I: IntoIterator<Item = T>,
39{
40    let mut dest = vec![];
41    for element in elements {
42        dest.push_str(element);
43    }
44    dest
45}
46
47/// Join the elements given by the iterator with the given separator into a
48/// single `Vec<u8>`.
49///
50/// Both the separator and the elements may be any type that can be cheaply
51/// converted into an `&[u8]`. This includes, but is not limited to,
52/// `&str`, `&BStr` and `&[u8]` itself.
53///
54/// # Examples
55///
56/// Basic usage:
57///
58/// ```
59/// use bstr;
60///
61/// let s = bstr::join(",", &["foo", "bar", "baz"]);
62/// assert_eq!(s, "foo,bar,baz".as_bytes());
63/// ```
64#[inline]
65pub fn join<B, T, I>(separator: B, elements: I) -> Vec<u8>
66where
67    B: AsRef<[u8]>,
68    T: AsRef<[u8]>,
69    I: IntoIterator<Item = T>,
70{
71    let mut it = elements.into_iter();
72    let mut dest = vec![];
73    match it.next() {
74        None => return dest,
75        Some(first) => {
76            dest.push_str(first);
77        }
78    }
79    for element in it {
80        dest.push_str(&separator);
81        dest.push_str(element);
82    }
83    dest
84}
85
86impl ByteVec for Vec<u8> {
87    #[inline]
88    fn as_vec(&self) -> &Vec<u8> {
89        self
90    }
91
92    #[inline]
93    fn as_vec_mut(&mut self) -> &mut Vec<u8> {
94        self
95    }
96
97    #[inline]
98    fn into_vec(self) -> Vec<u8> {
99        self
100    }
101}
102
103/// Ensure that callers cannot implement `ByteSlice` by making an
104/// umplementable trait its super trait.
105mod private {
106    pub trait Sealed {}
107}
108impl private::Sealed for Vec<u8> {}
109
110/// A trait that extends `Vec<u8>` with string oriented methods.
111///
112/// Note that when using the constructor methods, such as
113/// `ByteVec::from_slice`, one should actually call them using the concrete
114/// type. For example:
115///
116/// ```
117/// use bstr::{B, ByteVec};
118///
119/// let s = Vec::from_slice(b"abc"); // NOT ByteVec::from_slice("...")
120/// assert_eq!(s, B("abc"));
121/// ```
122///
123/// This trait is sealed and cannot be implemented outside of `bstr`.
124pub trait ByteVec: private::Sealed {
125    /// A method for accessing the raw vector bytes of this type. This is
126    /// always a no-op and callers shouldn't care about it. This only exists
127    /// for making the extension trait work.
128    #[doc(hidden)]
129    fn as_vec(&self) -> &Vec<u8>;
130
131    /// A method for accessing the raw vector bytes of this type, mutably. This
132    /// is always a no-op and callers shouldn't care about it. This only exists
133    /// for making the extension trait work.
134    #[doc(hidden)]
135    fn as_vec_mut(&mut self) -> &mut Vec<u8>;
136
137    /// A method for consuming ownership of this vector. This is always a no-op
138    /// and callers shouldn't care about it. This only exists for making the
139    /// extension trait work.
140    #[doc(hidden)]
141    fn into_vec(self) -> Vec<u8>
142    where
143        Self: Sized;
144
145    /// Convert this type to a `BString`.
146    ///
147    /// `BString` is useful if you want its trait implementations such as `Debug`, `PartialEq`, and
148    /// `PartialOrd`, or if you want to declare at an interface boundary (field or parameter) that
149    /// something uses "conventionally UTF-8" owned strings.
150    ///
151    /// This is a zero-cost conversion.
152    ///
153    /// # Examples
154    ///
155    /// Basic usage:
156    ///
157    /// ```
158    /// use bstr::ByteVec;
159    ///
160    /// let v = vec![b'a', b'b', b'c'];
161    /// let b = v.to_bstring();
162    /// println!("{b}");
163    /// assert_eq!(b, "abc");
164    /// assert_ne!(b, "hello");
165    /// ```
166    #[inline]
167    fn to_bstring(self) -> BString
168    where
169        Self: Sized,
170    {
171        BString::new(self.into_vec())
172    }
173
174    /// Convert a `&Vec<u8>` to a `&BString`, without copying.
175    ///
176    /// `BString` is useful if you want its trait implementations such as `Debug`, `PartialEq`, and
177    /// `PartialOrd`, or if you want to declare at an interface boundary (field or parameter) that
178    /// something uses "conventionally UTF-8" owned strings.
179    ///
180    /// # Examples
181    ///
182    /// Basic usage:
183    ///
184    /// ```
185    /// use bstr::ByteVec;
186    ///
187    /// let mut v = vec![b'a', b'b', b'c'];
188    /// let b = v.as_bstring();
189    /// println!("{b}");
190    /// assert_eq!(b, "abc");
191    /// assert_ne!(b, "hello");
192    /// // no references to `b` after this point
193    /// v.push(b'd');
194    /// assert_eq!(v, [b'a', b'b', b'c', b'd']);
195    /// ```
196    #[inline]
197    fn as_bstring(&self) -> &BString {
198        BString::from_vec_ref(self.as_vec())
199    }
200
201    /// Convert a `&mut Vec<u8>` to a `&mut BString`, without copying.
202    ///
203    /// `BString` is useful if you want its trait implementations such as `Debug`, `PartialEq`, and
204    /// `PartialOrd`, or if you want to declare at an interface boundary (field or parameter) that
205    /// something uses "conventionally UTF-8" owned strings.
206    ///
207    /// # Examples
208    ///
209    /// Basic usage:
210    ///
211    /// ```
212    /// use bstr::ByteVec;
213    ///
214    /// let mut v = vec![b'a', b'b', b'c'];
215    /// let b = v.as_bstring_mut();
216    /// println!("{b}");
217    /// assert_eq!(b, "abc");
218    /// assert_ne!(b, "hello");
219    /// b.push_str("de");
220    /// assert_eq!(v, [b'a', b'b', b'c', b'd', b'e']);
221    /// ```
222    #[inline]
223    fn as_bstring_mut(&mut self) -> &mut BString {
224        BString::from_vec_mut(self.as_vec_mut())
225    }
226
227    /// Create a new owned byte string from the given byte slice.
228    ///
229    /// # Examples
230    ///
231    /// Basic usage:
232    ///
233    /// ```
234    /// use bstr::{B, ByteVec};
235    ///
236    /// let s = Vec::from_slice(b"abc");
237    /// assert_eq!(s, B("abc"));
238    /// ```
239    #[inline]
240    fn from_slice<B: AsRef<[u8]>>(bytes: B) -> Vec<u8> {
241        bytes.as_ref().to_vec()
242    }
243
244    /// Create a new byte string from an owned OS string.
245    ///
246    /// When the underlying bytes of OS strings are accessible, then this
247    /// always succeeds and is zero cost. Otherwise, this returns the given
248    /// `OsString` if it is not valid UTF-8.
249    ///
250    /// # Examples
251    ///
252    /// Basic usage:
253    ///
254    /// ```
255    /// use std::ffi::OsString;
256    ///
257    /// use bstr::{B, ByteVec};
258    ///
259    /// let os_str = OsString::from("foo");
260    /// let bs = Vec::from_os_string(os_str).expect("valid UTF-8");
261    /// assert_eq!(bs, B("foo"));
262    /// ```
263    #[inline]
264    #[cfg(feature = "std")]
265    fn from_os_string(os_str: OsString) -> Result<Vec<u8>, OsString> {
266        #[cfg(unix)]
267        #[inline]
268        fn imp(os_str: OsString) -> Result<Vec<u8>, OsString> {
269            use std::os::unix::ffi::OsStringExt;
270
271            Ok(os_str.into_vec())
272        }
273
274        #[cfg(not(unix))]
275        #[inline]
276        fn imp(os_str: OsString) -> Result<Vec<u8>, OsString> {
277            os_str.into_string().map(Vec::from)
278        }
279
280        imp(os_str)
281    }
282
283    /// Lossily create a new byte string from an OS string slice.
284    ///
285    /// When the underlying bytes of OS strings are accessible, then this is
286    /// zero cost and always returns a slice. Otherwise, a UTF-8 check is
287    /// performed and if the given OS string is not valid UTF-8, then it is
288    /// lossily decoded into valid UTF-8 (with invalid bytes replaced by the
289    /// Unicode replacement codepoint).
290    ///
291    /// # Examples
292    ///
293    /// Basic usage:
294    ///
295    /// ```
296    /// use std::ffi::OsStr;
297    ///
298    /// use bstr::{B, ByteVec};
299    ///
300    /// let os_str = OsStr::new("foo");
301    /// let bs = Vec::from_os_str_lossy(os_str);
302    /// assert_eq!(bs, B("foo"));
303    /// ```
304    #[inline]
305    #[cfg(feature = "std")]
306    fn from_os_str_lossy(os_str: &OsStr) -> Cow<'_, [u8]> {
307        #[cfg(unix)]
308        #[inline]
309        fn imp(os_str: &OsStr) -> Cow<'_, [u8]> {
310            use std::os::unix::ffi::OsStrExt;
311
312            Cow::Borrowed(os_str.as_bytes())
313        }
314
315        #[cfg(not(unix))]
316        #[inline]
317        fn imp(os_str: &OsStr) -> Cow<'_, [u8]> {
318            match os_str.to_string_lossy() {
319                Cow::Borrowed(x) => Cow::Borrowed(x.as_bytes()),
320                Cow::Owned(x) => Cow::Owned(Vec::from(x)),
321            }
322        }
323
324        imp(os_str)
325    }
326
327    /// Create a new byte string from an owned file path.
328    ///
329    /// When the underlying bytes of paths are accessible, then this always
330    /// succeeds and is zero cost. Otherwise, this returns the given `PathBuf`
331    /// if it is not valid UTF-8.
332    ///
333    /// # Examples
334    ///
335    /// Basic usage:
336    ///
337    /// ```
338    /// use std::path::PathBuf;
339    ///
340    /// use bstr::{B, ByteVec};
341    ///
342    /// let path = PathBuf::from("foo");
343    /// let bs = Vec::from_path_buf(path).expect("must be valid UTF-8");
344    /// assert_eq!(bs, B("foo"));
345    /// ```
346    #[inline]
347    #[cfg(feature = "std")]
348    fn from_path_buf(path: PathBuf) -> Result<Vec<u8>, PathBuf> {
349        Vec::from_os_string(path.into_os_string()).map_err(PathBuf::from)
350    }
351
352    /// Lossily create a new byte string from a file path.
353    ///
354    /// When the underlying bytes of paths are accessible, then this is
355    /// zero cost and always returns a slice. Otherwise, a UTF-8 check is
356    /// performed and if the given path is not valid UTF-8, then it is lossily
357    /// decoded into valid UTF-8 (with invalid bytes replaced by the Unicode
358    /// replacement codepoint).
359    ///
360    /// # Examples
361    ///
362    /// Basic usage:
363    ///
364    /// ```
365    /// use std::path::Path;
366    ///
367    /// use bstr::{B, ByteVec};
368    ///
369    /// let path = Path::new("foo");
370    /// let bs = Vec::from_path_lossy(path);
371    /// assert_eq!(bs, B("foo"));
372    /// ```
373    #[inline]
374    #[cfg(feature = "std")]
375    fn from_path_lossy(path: &Path) -> Cow<'_, [u8]> {
376        Vec::from_os_str_lossy(path.as_os_str())
377    }
378
379    /// Unescapes the given string into its raw bytes.
380    ///
381    /// This looks for the escape sequences `\xNN`, `\0`, `\r`, `\n`, `\t`
382    /// and `\` and translates them into their corresponding unescaped form.
383    ///
384    /// Incomplete escape sequences or things that look like escape sequences
385    /// but are not (for example, `\i` or `\xYZ`) are passed through literally.
386    ///
387    /// This is the dual of [`ByteSlice::escape_bytes`].
388    ///
389    /// Note that the zero or NUL byte may be represented as either `\0` or
390    /// `\x00`. Both will be unescaped into the zero byte.
391    ///
392    /// # Examples
393    ///
394    /// This shows basic usage:
395    ///
396    /// ```
397    /// # #[cfg(feature = "alloc")] {
398    /// use bstr::{B, BString, ByteVec};
399    ///
400    /// assert_eq!(
401    ///     BString::from(b"foo\xFFbar"),
402    ///     Vec::unescape_bytes(r"foo\xFFbar"),
403    /// );
404    /// assert_eq!(
405    ///     BString::from(b"foo\nbar"),
406    ///     Vec::unescape_bytes(r"foo\nbar"),
407    /// );
408    /// assert_eq!(
409    ///     BString::from(b"foo\tbar"),
410    ///     Vec::unescape_bytes(r"foo\tbar"),
411    /// );
412    /// assert_eq!(
413    ///     BString::from(b"foo\\bar"),
414    ///     Vec::unescape_bytes(r"foo\\bar"),
415    /// );
416    /// assert_eq!(
417    ///     BString::from("foo☃bar"),
418    ///     Vec::unescape_bytes(r"foo☃bar"),
419    /// );
420    ///
421    /// # }
422    /// ```
423    ///
424    /// This shows some examples of how incomplete or "incorrect" escape
425    /// sequences get passed through literally.
426    ///
427    /// ```
428    /// # #[cfg(feature = "alloc")] {
429    /// use bstr::{B, BString, ByteVec};
430    ///
431    /// // Show some incomplete escape sequences.
432    /// assert_eq!(
433    ///     BString::from(br"\"),
434    ///     Vec::unescape_bytes(r"\"),
435    /// );
436    /// assert_eq!(
437    ///     BString::from(br"\"),
438    ///     Vec::unescape_bytes(r"\\"),
439    /// );
440    /// assert_eq!(
441    ///     BString::from(br"\x"),
442    ///     Vec::unescape_bytes(r"\x"),
443    /// );
444    /// assert_eq!(
445    ///     BString::from(br"\xA"),
446    ///     Vec::unescape_bytes(r"\xA"),
447    /// );
448    /// // And now some that kind of look like escape
449    /// // sequences, but aren't.
450    /// assert_eq!(
451    ///     BString::from(br"\xZ"),
452    ///     Vec::unescape_bytes(r"\xZ"),
453    /// );
454    /// assert_eq!(
455    ///     BString::from(br"\xZZ"),
456    ///     Vec::unescape_bytes(r"\xZZ"),
457    /// );
458    /// assert_eq!(
459    ///     BString::from(br"\i"),
460    ///     Vec::unescape_bytes(r"\i"),
461    /// );
462    /// assert_eq!(
463    ///     BString::from(br"\u"),
464    ///     Vec::unescape_bytes(r"\u"),
465    /// );
466    /// assert_eq!(
467    ///     BString::from(br"\u{2603}"),
468    ///     Vec::unescape_bytes(r"\u{2603}"),
469    /// );
470    ///
471    /// # }
472    /// ```
473    #[inline]
474    #[cfg(feature = "alloc")]
475    fn unescape_bytes<S: AsRef<str>>(escaped: S) -> Vec<u8> {
476        let s = escaped.as_ref();
477        crate::escape_bytes::UnescapeBytes::new(s.chars()).collect()
478    }
479
480    /// Appends the given byte to the end of this byte string.
481    ///
482    /// Note that this is equivalent to the generic `Vec::push` method. This
483    /// method is provided to permit callers to explicitly differentiate
484    /// between pushing bytes, codepoints and strings.
485    ///
486    /// # Examples
487    ///
488    /// Basic usage:
489    ///
490    /// ```
491    /// use bstr::ByteVec;
492    ///
493    /// let mut s = <Vec<u8>>::from("abc");
494    /// s.push_byte(b'\xE2');
495    /// s.push_byte(b'\x98');
496    /// s.push_byte(b'\x83');
497    /// assert_eq!(s, "abc☃".as_bytes());
498    /// ```
499    #[inline]
500    fn push_byte(&mut self, byte: u8) {
501        self.as_vec_mut().push(byte);
502    }
503
504    /// Appends the given `char` to the end of this byte string.
505    ///
506    /// # Examples
507    ///
508    /// Basic usage:
509    ///
510    /// ```
511    /// use bstr::ByteVec;
512    ///
513    /// let mut s = <Vec<u8>>::from("abc");
514    /// s.push_char('1');
515    /// s.push_char('2');
516    /// s.push_char('3');
517    /// assert_eq!(s, "abc123".as_bytes());
518    /// ```
519    #[inline]
520    fn push_char(&mut self, ch: char) {
521        if ch.len_utf8() == 1 {
522            self.push_byte(ch as u8);
523            return;
524        }
525        self.as_vec_mut()
526            .extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes());
527    }
528
529    /// Appends the given slice to the end of this byte string. This accepts
530    /// any type that be converted to a `&[u8]`. This includes, but is not
531    /// limited to, `&str`, `&BStr`, and of course, `&[u8]` itself.
532    ///
533    /// # Examples
534    ///
535    /// Basic usage:
536    ///
537    /// ```
538    /// use bstr::ByteVec;
539    ///
540    /// let mut s = <Vec<u8>>::from("abc");
541    /// s.push_str(b"123");
542    /// assert_eq!(s, "abc123".as_bytes());
543    /// ```
544    #[inline]
545    fn push_str<B: AsRef<[u8]>>(&mut self, bytes: B) {
546        self.as_vec_mut().extend_from_slice(bytes.as_ref());
547    }
548
549    /// Converts a `Vec<u8>` into a `String` if and only if this byte string is
550    /// valid UTF-8.
551    ///
552    /// If it is not valid UTF-8, then a
553    /// [`FromUtf8Error`](struct.FromUtf8Error.html)
554    /// is returned. (This error can be used to examine why UTF-8 validation
555    /// failed, or to regain the original byte string.)
556    ///
557    /// # Examples
558    ///
559    /// Basic usage:
560    ///
561    /// ```
562    /// use bstr::ByteVec;
563    ///
564    /// let bytes = Vec::from("hello");
565    /// let string = bytes.into_string().unwrap();
566    ///
567    /// assert_eq!("hello", string);
568    /// ```
569    ///
570    /// If this byte string is not valid UTF-8, then an error will be returned.
571    /// That error can then be used to inspect the location at which invalid
572    /// UTF-8 was found, or to regain the original byte string:
573    ///
574    /// ```
575    /// use bstr::{B, ByteVec};
576    ///
577    /// let bytes = Vec::from_slice(b"foo\xFFbar");
578    /// let err = bytes.into_string().unwrap_err();
579    ///
580    /// assert_eq!(err.utf8_error().valid_up_to(), 3);
581    /// assert_eq!(err.utf8_error().error_len(), Some(1));
582    ///
583    /// // At no point in this example is an allocation performed.
584    /// let bytes = Vec::from(err.into_vec());
585    /// assert_eq!(bytes, B(b"foo\xFFbar"));
586    /// ```
587    #[inline]
588    fn into_string(self) -> Result<String, FromUtf8Error>
589    where
590        Self: Sized,
591    {
592        match utf8::validate(self.as_vec()) {
593            Err(err) => Err(FromUtf8Error { original: self.into_vec(), err }),
594            Ok(()) => {
595                // SAFETY: This is safe because of the guarantees provided by
596                // utf8::validate.
597                unsafe { Ok(self.into_string_unchecked()) }
598            }
599        }
600    }
601
602    /// Lossily converts a `Vec<u8>` into a `String`. If this byte string
603    /// contains invalid UTF-8, then the invalid bytes are replaced with the
604    /// Unicode replacement codepoint.
605    ///
606    /// # Examples
607    ///
608    /// Basic usage:
609    ///
610    /// ```
611    /// use bstr::ByteVec;
612    ///
613    /// let bytes = Vec::from_slice(b"foo\xFFbar");
614    /// let string = bytes.into_string_lossy();
615    /// assert_eq!(string, "foo\u{FFFD}bar");
616    /// ```
617    #[inline]
618    fn into_string_lossy(self) -> String
619    where
620        Self: Sized,
621    {
622        match self.as_vec().to_str_lossy() {
623            Cow::Borrowed(_) => {
624                // SAFETY: to_str_lossy() returning a Cow::Borrowed guarantees
625                // the entire string is valid utf8.
626                unsafe { self.into_string_unchecked() }
627            }
628            Cow::Owned(s) => s,
629        }
630    }
631
632    /// Unsafely convert this byte string into a `String`, without checking for
633    /// valid UTF-8.
634    ///
635    /// # Safety
636    ///
637    /// Callers *must* ensure that this byte string is valid UTF-8 before
638    /// calling this method. Converting a byte string into a `String` that is
639    /// not valid UTF-8 is considered undefined behavior.
640    ///
641    /// This routine is useful in performance sensitive contexts where the
642    /// UTF-8 validity of the byte string is already known and it is
643    /// undesirable to pay the cost of an additional UTF-8 validation check
644    /// that [`into_string`](#method.into_string) performs.
645    ///
646    /// # Examples
647    ///
648    /// Basic usage:
649    ///
650    /// ```
651    /// use bstr::ByteVec;
652    ///
653    /// // SAFETY: This is safe because string literals are guaranteed to be
654    /// // valid UTF-8 by the Rust compiler.
655    /// let s = unsafe { Vec::from("☃βツ").into_string_unchecked() };
656    /// assert_eq!("☃βツ", s);
657    /// ```
658    #[inline]
659    unsafe fn into_string_unchecked(self) -> String
660    where
661        Self: Sized,
662    {
663        String::from_utf8_unchecked(self.into_vec())
664    }
665
666    /// Converts this byte string into an OS string, in place.
667    ///
668    /// When OS strings can be constructed from arbitrary byte sequences, this
669    /// always succeeds and is zero cost. Otherwise, if this byte string is not
670    /// valid UTF-8, then an error (with the original byte string) is returned.
671    ///
672    /// # Examples
673    ///
674    /// Basic usage:
675    ///
676    /// ```
677    /// use std::ffi::OsStr;
678    ///
679    /// use bstr::ByteVec;
680    ///
681    /// let bs = Vec::from("foo");
682    /// let os_str = bs.into_os_string().expect("should be valid UTF-8");
683    /// assert_eq!(os_str, OsStr::new("foo"));
684    /// ```
685    #[cfg(feature = "std")]
686    #[inline]
687    fn into_os_string(self) -> Result<OsString, FromUtf8Error>
688    where
689        Self: Sized,
690    {
691        #[cfg(unix)]
692        #[inline]
693        fn imp(v: Vec<u8>) -> Result<OsString, FromUtf8Error> {
694            use std::os::unix::ffi::OsStringExt;
695
696            Ok(OsString::from_vec(v))
697        }
698
699        #[cfg(not(unix))]
700        #[inline]
701        fn imp(v: Vec<u8>) -> Result<OsString, FromUtf8Error> {
702            v.into_string().map(OsString::from)
703        }
704
705        imp(self.into_vec())
706    }
707
708    /// Lossily converts this byte string into an OS string, in place.
709    ///
710    /// When OS strings can be constructed from arbitrary byte sequences, this
711    /// is zero cost and always returns a slice. Otherwise, this will perform a
712    /// UTF-8 check and lossily convert this byte string into valid UTF-8 using
713    /// the Unicode replacement codepoint.
714    ///
715    /// Note that this can prevent the correct roundtripping of file paths when
716    /// the representation of `OsString` is opaque.
717    ///
718    /// # Examples
719    ///
720    /// Basic usage:
721    ///
722    /// ```
723    /// use bstr::ByteVec;
724    ///
725    /// let bs = Vec::from_slice(b"foo\xFFbar");
726    /// let os_str = bs.into_os_string_lossy();
727    /// assert_eq!(os_str.to_string_lossy(), "foo\u{FFFD}bar");
728    /// ```
729    #[inline]
730    #[cfg(feature = "std")]
731    fn into_os_string_lossy(self) -> OsString
732    where
733        Self: Sized,
734    {
735        #[cfg(unix)]
736        #[inline]
737        fn imp(v: Vec<u8>) -> OsString {
738            use std::os::unix::ffi::OsStringExt;
739
740            OsString::from_vec(v)
741        }
742
743        #[cfg(not(unix))]
744        #[inline]
745        fn imp(v: Vec<u8>) -> OsString {
746            OsString::from(v.into_string_lossy())
747        }
748
749        imp(self.into_vec())
750    }
751
752    /// Converts this byte string into an owned file path, in place.
753    ///
754    /// When paths can be constructed from arbitrary byte sequences, this
755    /// always succeeds and is zero cost. Otherwise, if this byte string is not
756    /// valid UTF-8, then an error (with the original byte string) is returned.
757    ///
758    /// # Examples
759    ///
760    /// Basic usage:
761    ///
762    /// ```
763    /// use bstr::ByteVec;
764    ///
765    /// let bs = Vec::from("foo");
766    /// let path = bs.into_path_buf().expect("should be valid UTF-8");
767    /// assert_eq!(path.as_os_str(), "foo");
768    /// ```
769    #[cfg(feature = "std")]
770    #[inline]
771    fn into_path_buf(self) -> Result<PathBuf, FromUtf8Error>
772    where
773        Self: Sized,
774    {
775        self.into_os_string().map(PathBuf::from)
776    }
777
778    /// Lossily converts this byte string into an owned file path, in place.
779    ///
780    /// When paths can be constructed from arbitrary byte sequences, this is
781    /// zero cost and always returns a slice. Otherwise, this will perform a
782    /// UTF-8 check and lossily convert this byte string into valid UTF-8 using
783    /// the Unicode replacement codepoint.
784    ///
785    /// Note that this can prevent the correct roundtripping of file paths when
786    /// the representation of `PathBuf` is opaque.
787    ///
788    /// # Examples
789    ///
790    /// Basic usage:
791    ///
792    /// ```
793    /// use bstr::ByteVec;
794    ///
795    /// let bs = Vec::from_slice(b"foo\xFFbar");
796    /// let path = bs.into_path_buf_lossy();
797    /// assert_eq!(path.to_string_lossy(), "foo\u{FFFD}bar");
798    /// ```
799    #[inline]
800    #[cfg(feature = "std")]
801    fn into_path_buf_lossy(self) -> PathBuf
802    where
803        Self: Sized,
804    {
805        PathBuf::from(self.into_os_string_lossy())
806    }
807
808    /// Removes the last byte from this `Vec<u8>` and returns it.
809    ///
810    /// If this byte string is empty, then `None` is returned.
811    ///
812    /// If the last codepoint in this byte string is not ASCII, then removing
813    /// the last byte could make this byte string contain invalid UTF-8.
814    ///
815    /// Note that this is equivalent to the generic `Vec::pop` method. This
816    /// method is provided to permit callers to explicitly differentiate
817    /// between popping bytes and codepoints.
818    ///
819    /// # Examples
820    ///
821    /// Basic usage:
822    ///
823    /// ```
824    /// use bstr::ByteVec;
825    ///
826    /// let mut s = Vec::from("foo");
827    /// assert_eq!(s.pop_byte(), Some(b'o'));
828    /// assert_eq!(s.pop_byte(), Some(b'o'));
829    /// assert_eq!(s.pop_byte(), Some(b'f'));
830    /// assert_eq!(s.pop_byte(), None);
831    /// ```
832    #[inline]
833    fn pop_byte(&mut self) -> Option<u8> {
834        self.as_vec_mut().pop()
835    }
836
837    /// Removes the last codepoint from this `Vec<u8>` and returns it.
838    ///
839    /// If this byte string is empty, then `None` is returned. If the last
840    /// bytes of this byte string do not correspond to a valid UTF-8 code unit
841    /// sequence, then the Unicode replacement codepoint is yielded instead in
842    /// accordance with the
843    /// [replacement codepoint substitution policy](index.html#handling-of-invalid-utf8-8).
844    ///
845    /// # Examples
846    ///
847    /// Basic usage:
848    ///
849    /// ```
850    /// use bstr::ByteVec;
851    ///
852    /// let mut s = Vec::from("foo");
853    /// assert_eq!(s.pop_char(), Some('o'));
854    /// assert_eq!(s.pop_char(), Some('o'));
855    /// assert_eq!(s.pop_char(), Some('f'));
856    /// assert_eq!(s.pop_char(), None);
857    /// ```
858    ///
859    /// This shows the replacement codepoint substitution policy. Note that
860    /// the first pop yields a replacement codepoint but actually removes two
861    /// bytes. This is in contrast with subsequent pops when encountering
862    /// `\xFF` since `\xFF` is never a valid prefix for any valid UTF-8
863    /// code unit sequence.
864    ///
865    /// ```
866    /// use bstr::ByteVec;
867    ///
868    /// let mut s = Vec::from_slice(b"f\xFF\xFF\xFFoo\xE2\x98");
869    /// assert_eq!(s.pop_char(), Some('\u{FFFD}'));
870    /// assert_eq!(s.pop_char(), Some('o'));
871    /// assert_eq!(s.pop_char(), Some('o'));
872    /// assert_eq!(s.pop_char(), Some('\u{FFFD}'));
873    /// assert_eq!(s.pop_char(), Some('\u{FFFD}'));
874    /// assert_eq!(s.pop_char(), Some('\u{FFFD}'));
875    /// assert_eq!(s.pop_char(), Some('f'));
876    /// assert_eq!(s.pop_char(), None);
877    /// ```
878    #[inline]
879    fn pop_char(&mut self) -> Option<char> {
880        let (ch, size) = utf8::decode_last_lossy(self.as_vec());
881        if size == 0 {
882            return None;
883        }
884        let new_len = self.as_vec().len() - size;
885        self.as_vec_mut().truncate(new_len);
886        Some(ch)
887    }
888
889    /// Removes a `char` from this `Vec<u8>` at the given byte position and
890    /// returns it.
891    ///
892    /// If the bytes at the given position do not lead to a valid UTF-8 code
893    /// unit sequence, then a
894    /// [replacement codepoint is returned instead](index.html#handling-of-invalid-utf8-8).
895    ///
896    /// # Panics
897    ///
898    /// Panics if `at` is larger than or equal to this byte string's length.
899    ///
900    /// # Examples
901    ///
902    /// Basic usage:
903    ///
904    /// ```
905    /// use bstr::ByteVec;
906    ///
907    /// let mut s = Vec::from("foo☃bar");
908    /// assert_eq!(s.remove_char(3), '☃');
909    /// assert_eq!(s, b"foobar");
910    /// ```
911    ///
912    /// This example shows how the Unicode replacement codepoint policy is
913    /// used:
914    ///
915    /// ```
916    /// use bstr::ByteVec;
917    ///
918    /// let mut s = Vec::from_slice(b"foo\xFFbar");
919    /// assert_eq!(s.remove_char(3), '\u{FFFD}');
920    /// assert_eq!(s, b"foobar");
921    /// ```
922    #[inline]
923    fn remove_char(&mut self, at: usize) -> char {
924        let (ch, size) = utf8::decode_lossy(&self.as_vec()[at..]);
925        assert!(
926            size > 0,
927            "expected {} to be less than {}",
928            at,
929            self.as_vec().len(),
930        );
931        self.as_vec_mut().drain(at..at + size);
932        ch
933    }
934
935    /// Inserts the given codepoint into this `Vec<u8>` at a particular byte
936    /// position.
937    ///
938    /// This is an `O(n)` operation as it may copy a number of elements in this
939    /// byte string proportional to its length.
940    ///
941    /// # Panics
942    ///
943    /// Panics if `at` is larger than the byte string's length.
944    ///
945    /// # Examples
946    ///
947    /// Basic usage:
948    ///
949    /// ```
950    /// use bstr::ByteVec;
951    ///
952    /// let mut s = Vec::from("foobar");
953    /// s.insert_char(3, '☃');
954    /// assert_eq!(s, "foo☃bar".as_bytes());
955    /// ```
956    #[inline]
957    fn insert_char(&mut self, at: usize, ch: char) {
958        self.insert_str(at, ch.encode_utf8(&mut [0; 4]).as_bytes());
959    }
960
961    /// Inserts the given byte string into this byte string at a particular
962    /// byte position.
963    ///
964    /// This is an `O(n)` operation as it may copy a number of elements in this
965    /// byte string proportional to its length.
966    ///
967    /// The given byte string may be any type that can be cheaply converted
968    /// into a `&[u8]`. This includes, but is not limited to, `&str` and
969    /// `&[u8]`.
970    ///
971    /// # Panics
972    ///
973    /// Panics if `at` is larger than the byte string's length.
974    ///
975    /// # Examples
976    ///
977    /// Basic usage:
978    ///
979    /// ```
980    /// use bstr::ByteVec;
981    ///
982    /// let mut s = Vec::from("foobar");
983    /// s.insert_str(3, "☃☃☃");
984    /// assert_eq!(s, "foo☃☃☃bar".as_bytes());
985    /// ```
986    #[inline]
987    fn insert_str<B: AsRef<[u8]>>(&mut self, at: usize, bytes: B) {
988        let bytes = bytes.as_ref();
989        let len = self.as_vec().len();
990        assert!(at <= len, "expected {} to be <= {}", at, len);
991
992        // SAFETY: We'd like to efficiently splice in the given bytes into
993        // this byte string. Since we are only working with `u8` elements here,
994        // we only need to consider whether our bounds are correct and whether
995        // our byte string has enough space.
996        self.as_vec_mut().reserve(bytes.len());
997        unsafe {
998            // Shift bytes after `at` over by the length of `bytes` to make
999            // room for it. This requires referencing two regions of memory
1000            // that may overlap, so we use ptr::copy.
1001            ptr::copy(
1002                self.as_vec().as_ptr().add(at),
1003                self.as_vec_mut().as_mut_ptr().add(at + bytes.len()),
1004                len - at,
1005            );
1006            // Now copy the bytes given into the room we made above. In this
1007            // case, we know that the given bytes cannot possibly overlap
1008            // with this byte string since we have a mutable borrow of the
1009            // latter. Thus, we can use a nonoverlapping copy.
1010            ptr::copy_nonoverlapping(
1011                bytes.as_ptr(),
1012                self.as_vec_mut().as_mut_ptr().add(at),
1013                bytes.len(),
1014            );
1015            self.as_vec_mut().set_len(len + bytes.len());
1016        }
1017    }
1018
1019    /// Removes the specified range in this byte string and replaces it with
1020    /// the given bytes. The given bytes do not need to have the same length
1021    /// as the range provided.
1022    ///
1023    /// # Panics
1024    ///
1025    /// Panics if the given range is invalid.
1026    ///
1027    /// # Examples
1028    ///
1029    /// Basic usage:
1030    ///
1031    /// ```
1032    /// use bstr::ByteVec;
1033    ///
1034    /// let mut s = Vec::from("foobar");
1035    /// s.replace_range(2..4, "xxxxx");
1036    /// assert_eq!(s, "foxxxxxar".as_bytes());
1037    /// ```
1038    #[inline]
1039    fn replace_range<R, B>(&mut self, range: R, replace_with: B)
1040    where
1041        R: ops::RangeBounds<usize>,
1042        B: AsRef<[u8]>,
1043    {
1044        self.as_vec_mut().splice(range, replace_with.as_ref().iter().copied());
1045    }
1046
1047    /// Creates a draining iterator that removes the specified range in this
1048    /// `Vec<u8>` and yields each of the removed bytes.
1049    ///
1050    /// Note that the elements specified by the given range are removed
1051    /// regardless of whether the returned iterator is fully exhausted.
1052    ///
1053    /// Also note that is is unspecified how many bytes are removed from the
1054    /// `Vec<u8>` if the `DrainBytes` iterator is leaked.
1055    ///
1056    /// # Panics
1057    ///
1058    /// Panics if the given range is not valid.
1059    ///
1060    /// # Examples
1061    ///
1062    /// Basic usage:
1063    ///
1064    /// ```
1065    /// use bstr::ByteVec;
1066    ///
1067    /// let mut s = Vec::from("foobar");
1068    /// {
1069    ///     let mut drainer = s.drain_bytes(2..4);
1070    ///     assert_eq!(drainer.next(), Some(b'o'));
1071    ///     assert_eq!(drainer.next(), Some(b'b'));
1072    ///     assert_eq!(drainer.next(), None);
1073    /// }
1074    /// assert_eq!(s, "foar".as_bytes());
1075    /// ```
1076    #[inline]
1077    fn drain_bytes<R>(&mut self, range: R) -> DrainBytes<'_>
1078    where
1079        R: ops::RangeBounds<usize>,
1080    {
1081        DrainBytes { it: self.as_vec_mut().drain(range) }
1082    }
1083}
1084
1085/// A draining byte oriented iterator for `Vec<u8>`.
1086///
1087/// This iterator is created by
1088/// [`ByteVec::drain_bytes`](trait.ByteVec.html#method.drain_bytes).
1089///
1090/// # Examples
1091///
1092/// Basic usage:
1093///
1094/// ```
1095/// use bstr::ByteVec;
1096///
1097/// let mut s = Vec::from("foobar");
1098/// {
1099///     let mut drainer = s.drain_bytes(2..4);
1100///     assert_eq!(drainer.next(), Some(b'o'));
1101///     assert_eq!(drainer.next(), Some(b'b'));
1102///     assert_eq!(drainer.next(), None);
1103/// }
1104/// assert_eq!(s, "foar".as_bytes());
1105/// ```
1106#[derive(Debug)]
1107pub struct DrainBytes<'a> {
1108    it: vec::Drain<'a, u8>,
1109}
1110
1111impl<'a> iter::FusedIterator for DrainBytes<'a> {}
1112
1113impl<'a> Iterator for DrainBytes<'a> {
1114    type Item = u8;
1115
1116    #[inline]
1117    fn next(&mut self) -> Option<u8> {
1118        self.it.next()
1119    }
1120}
1121
1122impl<'a> DoubleEndedIterator for DrainBytes<'a> {
1123    #[inline]
1124    fn next_back(&mut self) -> Option<u8> {
1125        self.it.next_back()
1126    }
1127}
1128
1129impl<'a> ExactSizeIterator for DrainBytes<'a> {
1130    #[inline]
1131    fn len(&self) -> usize {
1132        self.it.len()
1133    }
1134}
1135
1136/// An error that may occur when converting a `Vec<u8>` to a `String`.
1137///
1138/// This error includes the original `Vec<u8>` that failed to convert to a
1139/// `String`. This permits callers to recover the allocation used even if it
1140/// it not valid UTF-8.
1141///
1142/// # Examples
1143///
1144/// Basic usage:
1145///
1146/// ```
1147/// use bstr::{B, ByteVec};
1148///
1149/// let bytes = Vec::from_slice(b"foo\xFFbar");
1150/// let err = bytes.into_string().unwrap_err();
1151///
1152/// assert_eq!(err.utf8_error().valid_up_to(), 3);
1153/// assert_eq!(err.utf8_error().error_len(), Some(1));
1154///
1155/// // At no point in this example is an allocation performed.
1156/// let bytes = Vec::from(err.into_vec());
1157/// assert_eq!(bytes, B(b"foo\xFFbar"));
1158/// ```
1159#[derive(Debug, Eq, PartialEq)]
1160pub struct FromUtf8Error {
1161    original: Vec<u8>,
1162    err: Utf8Error,
1163}
1164
1165impl FromUtf8Error {
1166    /// Return the original bytes as a slice that failed to convert to a
1167    /// `String`.
1168    ///
1169    /// # Examples
1170    ///
1171    /// Basic usage:
1172    ///
1173    /// ```
1174    /// use bstr::{B, ByteVec};
1175    ///
1176    /// let bytes = Vec::from_slice(b"foo\xFFbar");
1177    /// let err = bytes.into_string().unwrap_err();
1178    ///
1179    /// // At no point in this example is an allocation performed.
1180    /// assert_eq!(err.as_bytes(), B(b"foo\xFFbar"));
1181    /// ```
1182    #[inline]
1183    pub fn as_bytes(&self) -> &[u8] {
1184        &self.original
1185    }
1186
1187    /// Consume this error and return the original byte string that failed to
1188    /// convert to a `String`.
1189    ///
1190    /// # Examples
1191    ///
1192    /// Basic usage:
1193    ///
1194    /// ```
1195    /// use bstr::{B, ByteVec};
1196    ///
1197    /// let bytes = Vec::from_slice(b"foo\xFFbar");
1198    /// let err = bytes.into_string().unwrap_err();
1199    /// let original = err.into_vec();
1200    ///
1201    /// // At no point in this example is an allocation performed.
1202    /// assert_eq!(original, B(b"foo\xFFbar"));
1203    /// ```
1204    #[inline]
1205    pub fn into_vec(self) -> Vec<u8> {
1206        self.original
1207    }
1208
1209    /// Return the underlying UTF-8 error that occurred. This error provides
1210    /// information on the nature and location of the invalid UTF-8 detected.
1211    ///
1212    /// # Examples
1213    ///
1214    /// Basic usage:
1215    ///
1216    /// ```
1217    /// use bstr::{B, ByteVec};
1218    ///
1219    /// let bytes = Vec::from_slice(b"foo\xFFbar");
1220    /// let err = bytes.into_string().unwrap_err();
1221    ///
1222    /// assert_eq!(err.utf8_error().valid_up_to(), 3);
1223    /// assert_eq!(err.utf8_error().error_len(), Some(1));
1224    /// ```
1225    #[inline]
1226    pub fn utf8_error(&self) -> &Utf8Error {
1227        &self.err
1228    }
1229}
1230
1231#[cfg(feature = "std")]
1232impl error::Error for FromUtf8Error {
1233    #[inline]
1234    fn description(&self) -> &str {
1235        "invalid UTF-8 vector"
1236    }
1237}
1238
1239impl fmt::Display for FromUtf8Error {
1240    #[inline]
1241    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1242        write!(f, "{}", self.err)
1243    }
1244}
1245
1246#[cfg(all(test, feature = "std"))]
1247mod tests {
1248    use alloc::{vec, vec::Vec};
1249
1250    use crate::ext_vec::ByteVec;
1251
1252    #[test]
1253    fn insert() {
1254        let mut s = vec![];
1255        s.insert_str(0, "foo");
1256        assert_eq!(s, "foo".as_bytes());
1257
1258        let mut s = Vec::from("a");
1259        s.insert_str(0, "foo");
1260        assert_eq!(s, "fooa".as_bytes());
1261
1262        let mut s = Vec::from("a");
1263        s.insert_str(1, "foo");
1264        assert_eq!(s, "afoo".as_bytes());
1265
1266        let mut s = Vec::from("foobar");
1267        s.insert_str(3, "quux");
1268        assert_eq!(s, "fooquuxbar".as_bytes());
1269
1270        let mut s = Vec::from("foobar");
1271        s.insert_str(3, "x");
1272        assert_eq!(s, "fooxbar".as_bytes());
1273
1274        let mut s = Vec::from("foobar");
1275        s.insert_str(0, "x");
1276        assert_eq!(s, "xfoobar".as_bytes());
1277
1278        let mut s = Vec::from("foobar");
1279        s.insert_str(6, "x");
1280        assert_eq!(s, "foobarx".as_bytes());
1281
1282        let mut s = Vec::from("foobar");
1283        s.insert_str(3, "quuxbazquux");
1284        assert_eq!(s, "fooquuxbazquuxbar".as_bytes());
1285    }
1286
1287    #[test]
1288    #[should_panic]
1289    fn insert_fail1() {
1290        let mut s = vec![];
1291        s.insert_str(1, "foo");
1292    }
1293
1294    #[test]
1295    #[should_panic]
1296    fn insert_fail2() {
1297        let mut s = Vec::from("a");
1298        s.insert_str(2, "foo");
1299    }
1300
1301    #[test]
1302    #[should_panic]
1303    fn insert_fail3() {
1304        let mut s = Vec::from("foobar");
1305        s.insert_str(7, "foo");
1306    }
1307}