bstr/
bstring.rs

1use std::borrow::Cow;
2use std::error;
3use std::ffi::{OsStr, OsString};
4use std::fmt;
5use std::iter;
6use std::ops;
7use std::path::{Path, PathBuf};
8use std::ptr;
9use std::str;
10use std::vec;
11
12use bstr::BStr;
13use utf8::{self, Utf8Error};
14
15/// Concatenate the elements given by the iterator together into a single
16/// `BString`.
17///
18/// The elements may be any type that can be cheaply converted into an `&[u8]`.
19/// This includes, but is not limited to, `&str`, `&BStr` and `&[u8]` itself.
20///
21/// # Examples
22///
23/// Basic usage:
24///
25/// ```
26/// use bstr;
27///
28/// let s = bstr::concat(&["foo", "bar", "baz"]);
29/// assert_eq!(s, "foobarbaz");
30/// ```
31#[inline]
32pub fn concat<T, I>(
33    elements: I,
34) -> BString
35where T: AsRef<[u8]>,
36      I: IntoIterator<Item=T>
37{
38    let mut dest = BString::new();
39    for element in elements {
40        dest.push(element);
41    }
42    dest
43}
44
45/// Join the elements given by the iterator with the given separator into a
46/// single `BString`.
47///
48/// Both the separator and the elements may be any type that can be cheaply
49/// converted into an `&[u8]`. This includes, but is not limited to,
50/// `&str`, `&BStr` and `&[u8]` itself.
51///
52/// # Examples
53///
54/// Basic usage:
55///
56/// ```
57/// use bstr;
58///
59/// let s = bstr::join(",", &["foo", "bar", "baz"]);
60/// assert_eq!(s, "foo,bar,baz");
61/// ```
62#[inline]
63pub fn join<B, T, I>(
64    separator: B,
65    elements: I,
66) -> BString
67where B: AsRef<[u8]>,
68      T: AsRef<[u8]>,
69      I: IntoIterator<Item=T>
70{
71    let mut it = elements.into_iter();
72    let mut dest = BString::new();
73    match it.next() {
74        None => return dest,
75        Some(first) => {
76            dest.push(first);
77        }
78    }
79    for element in it {
80        dest.push(&separator);
81        dest.push(element);
82    }
83    dest
84}
85
86/// A growable byte string that is conventionally UTF-8.
87///
88/// A `BString` has ownership over its contents and corresponds to
89/// a growable or shrinkable buffer. Its borrowed counterpart is a
90/// [`BStr`](struct.BStr.html), called a byte string slice.
91///
92/// # Examples
93///
94/// You can create a new `BString` from a literal Unicode string or a literal
95/// byte string with `BString::from`:
96///
97/// ```
98/// use bstr::BString;
99///
100/// let s = BString::from("Hello, world!");
101/// ```
102///
103/// You can append bytes, characters or other strings to a `BString`:
104///
105/// ```
106/// use bstr::BString;
107///
108/// let mut s = BString::from("Hello, ");
109/// s.push_byte(b'w');
110/// s.push_char('o');
111/// s.push("rl");
112/// s.push(b"d!");
113/// assert_eq!(s, "Hello, world!");
114/// ```
115///
116/// If you have a `String` or a `Vec<u8>`, then you can create a `BString`
117/// from it with zero cost:
118///
119/// ```
120/// use bstr::BString;
121///
122/// let s = BString::from(vec![b'f', b'o', b'o']);
123/// let s = BString::from("foo".to_string());
124/// ```
125///
126/// A `BString` can be freely converted back to a `Vec<u8>`:
127///
128/// ```
129/// use bstr::BString;
130///
131/// let s = BString::from("foo");
132/// let vector = s.into_vec();
133/// assert_eq!(vector, vec![b'f', b'o', b'o']);
134/// ```
135///
136/// However, converting from a `BString` to a `String` requires UTF-8
137/// validation:
138///
139/// ```
140/// use bstr::BString;
141///
142/// # fn example() -> Result<(), ::bstr::FromUtf8Error> {
143/// let bytes = BString::from("hello");
144/// let string = bytes.into_string()?;
145///
146/// assert_eq!("hello", string);
147/// # Ok(()) }; example().unwrap()
148/// ```
149///
150/// # UTF-8
151///
152/// Like byte string slices (`BStr`), a `BString` is only conventionally
153/// UTF-8. This is in constrast to the standard library's `String` type, which
154/// is guaranteed to be valid UTF-8.
155///
156/// Because of this relaxation, types such as `Vec<u8>`, `&[u8]`, `String` and
157/// `&str` can all be converted to a `BString` (or `BStr`) at zero cost without
158/// any validation step.
159///
160/// Moreover, this relaxation implies that many of the restrictions around
161/// mutating a `String` do not apply to `BString`. Namely, if your `BString`
162/// is valid UTF-8, then the various methods that mutate the `BString` do not
163/// necessarily prevent you from causing the bytes to become invalid UTF-8.
164/// For example:
165///
166/// ```
167/// use bstr::{B, BString};
168///
169/// let mut s = BString::from("hello");
170/// s[1] = b'\xFF';
171/// // `s` was valid UTF-8, but now it's now.
172/// assert_eq!(s, B(b"h\xFFllo"));
173/// ```
174///
175/// # Deref
176///
177/// The `BString` type implements `Deref` and `DerefMut`, where the target
178/// types are `&BStr` and `&mut BStr`, respectively. `Deref` permits all of the
179/// methods defined on `BStr` to be implicitly callable on any `BString`.
180/// For example, the `contains` method is defined on `BStr` and not `BString`,
181/// but values of type `BString` can still use it directly:
182///
183/// ```
184/// use bstr::BString;
185///
186/// let s = BString::from("foobarbaz");
187/// assert!(s.contains("bar"));
188/// ```
189///
190/// For more information about how deref works, see the documentation for the
191/// [`std::ops::Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html)
192/// trait.
193///
194/// # Representation
195///
196/// A `BString` has the same representation as a `Vec<u8>` and a `String`.
197/// That is, it is made up of three word sized components: a pointer to a
198/// region of memory containing the bytes, a length and a capacity.
199#[derive(Clone, Hash)]
200pub struct BString {
201    bytes: Vec<u8>,
202}
203
204impl BString {
205    /// Creates a new empty `BString`.
206    ///
207    /// Given that the `BString` is empty, this will not allocate any initial
208    /// buffer. While that means that this initial operation is very
209    /// inexpensive, it may cause excessive allocation later when you add
210    /// data. If you have an idea of how much data the `String` will hold,
211    /// consider the [`with_capacity`] method to prevent excessive
212    /// re-allocation.
213    ///
214    /// [`with_capacity`]: #method.with_capacity
215    ///
216    /// # Examples
217    ///
218    /// Basic usage:
219    ///
220    /// ```
221    /// use bstr::BString;
222    ///
223    /// let s = BString::new();
224    /// ```
225    #[inline]
226    pub fn new() -> BString {
227        BString { bytes: vec![] }
228    }
229
230    /// Creates a new empty `BString` with a particular capacity.
231    ///
232    /// `BString`s have an internal buffer to hold their data. The capacity is
233    /// the length of that buffer, and can be queried with the [`capacity`]
234    /// method. This method creates an empty `BString`, but one with an initial
235    /// buffer that can hold `capacity` bytes. This is useful when you may be
236    /// appending a bunch of data to the `BString`, reducing the number of
237    /// reallocations it needs to do.
238    ///
239    /// [`capacity`]: #method.capacity
240    ///
241    /// If the given capacity is `0`, no allocation will occur, and this method
242    /// is identical to the [`new`] method.
243    ///
244    /// [`new`]: #method.new
245    ///
246    /// # Examples
247    ///
248    /// Basic usage:
249    ///
250    /// ```
251    /// use bstr::BString;
252    ///
253    /// let mut s = BString::with_capacity(10);
254    ///
255    /// // The String contains no chars, even though it has capacity for more
256    /// assert_eq!(s.len(), 0);
257    ///
258    /// // These are all done without reallocating...
259    /// let cap = s.capacity();
260    /// for i in 0..10 {
261    ///     s.push_char('a');
262    /// }
263    ///
264    /// assert_eq!(s.capacity(), cap);
265    ///
266    /// // ...but this may make the vector reallocate
267    /// s.push_char('a');
268    /// ```
269    #[inline]
270    pub fn with_capacity(capacity: usize) -> BString {
271        BString { bytes: Vec::with_capacity(capacity) }
272    }
273
274    /// Create a new byte string from the given bytes.
275    ///
276    /// # Examples
277    ///
278    /// Basic usage:
279    ///
280    /// ```
281    /// use bstr::BString;
282    ///
283    /// let bytes = vec![b'a', b'b', b'c'];
284    /// let s = BString::from_vec(bytes);
285    /// assert_eq!("abc", s);
286    /// ```
287    #[inline]
288    pub fn from_vec(bytes: Vec<u8>) -> BString {
289        BString { bytes }
290    }
291
292    /// Create a new byte string by copying the given slice.
293    ///
294    /// # Examples
295    ///
296    /// Basic usage:
297    ///
298    /// ```
299    /// use bstr::BString;
300    ///
301    /// let s = BString::from_slice(b"abc");
302    /// assert_eq!("abc", s);
303    /// ```
304    #[inline]
305    pub fn from_slice<B: AsRef<[u8]>>(slice: B) -> BString {
306        BString::from_vec(slice.as_ref().to_vec())
307    }
308
309    /// Create a new byte string from an owned OS string.
310    ///
311    /// On Unix, this always succeeds and is zero cost. On non-Unix systems,
312    /// this returns the original OS string if it is not valid UTF-8.
313    ///
314    /// # Examples
315    ///
316    /// Basic usage:
317    ///
318    /// ```
319    /// use std::ffi::OsString;
320    ///
321    /// use bstr::BString;
322    ///
323    /// let os_str = OsString::from("foo");
324    /// let bs = BString::from_os_string(os_str).expect("must be valid UTF-8");
325    /// assert_eq!(bs, "foo");
326    /// ```
327    #[inline]
328    pub fn from_os_string(os_str: OsString) -> Result<BString, OsString> {
329        BString::from_os_string_imp(os_str)
330    }
331
332    #[cfg(unix)]
333    fn from_os_string_imp(os_str: OsString) -> Result<BString, OsString> {
334        use std::os::unix::ffi::OsStringExt;
335
336        Ok(BString::from(os_str.into_vec()))
337    }
338
339    #[cfg(not(unix))]
340    fn from_os_string_imp(os_str: OsString) -> Result<BString, OsString> {
341        os_str.into_string().map(BString::from)
342    }
343
344    /// Lossily create a new byte string from an OS string slice.
345    ///
346    /// On Unix, this always succeeds, is zero cost and always returns a slice.
347    /// On non-Unix systems, this does a UTF-8 check. If the given OS string
348    /// slice is not valid UTF-8, then it is lossily decoded into valid UTF-8
349    /// (with invalid bytes replaced by the Unicode replacement codepoint).
350    ///
351    /// # Examples
352    ///
353    /// Basic usage:
354    ///
355    /// ```
356    /// use std::ffi::OsStr;
357    ///
358    /// use bstr::{B, BString};
359    ///
360    /// let os_str = OsStr::new("foo");
361    /// let bs = BString::from_os_str_lossy(os_str);
362    /// assert_eq!(bs, B("foo"));
363    /// ```
364    #[inline]
365    pub fn from_os_str_lossy<'a>(os_str: &'a OsStr) -> Cow<'a, BStr> {
366        BString::from_os_str_lossy_imp(os_str)
367    }
368
369    #[cfg(unix)]
370    fn from_os_str_lossy_imp<'a>(os_str: &'a OsStr) -> Cow<'a, BStr> {
371        use std::os::unix::ffi::OsStrExt;
372
373        Cow::Borrowed(BStr::new(os_str.as_bytes()))
374    }
375
376    #[cfg(not(unix))]
377    fn from_os_str_lossy_imp<'a>(os_str: &'a OsStr) -> Cow<'a, BStr> {
378        match os_str.to_string_lossy() {
379            Cow::Borrowed(x) => Cow::Borrowed(BStr::new(x)),
380            Cow::Owned(x) => Cow::Owned(BString::from(x)),
381        }
382    }
383
384    /// Create a new byte string from an owned file path.
385    ///
386    /// On Unix, this always succeeds and is zero cost. On non-Unix systems,
387    /// this returns the original path if it is not valid UTF-8.
388    ///
389    /// # Examples
390    ///
391    /// Basic usage:
392    ///
393    /// ```
394    /// use std::path::PathBuf;
395    ///
396    /// use bstr::BString;
397    ///
398    /// let path = PathBuf::from("foo");
399    /// let bs = BString::from_path_buf(path).expect("must be valid UTF-8");
400    /// assert_eq!(bs, "foo");
401    /// ```
402    #[inline]
403    pub fn from_path_buf(path: PathBuf) -> Result<BString, PathBuf> {
404        BString::from_os_string(path.into_os_string())
405            .map_err(PathBuf::from)
406    }
407
408    /// Lossily create a new byte string from a file path.
409    ///
410    /// On Unix, this always succeeds, is zero cost and always returns a slice.
411    /// On non-Unix systems, this does a UTF-8 check. If the given path is not
412    /// valid UTF-8, then it is lossily decoded into valid UTF-8 (with invalid
413    /// bytes replaced by the Unicode replacement codepoint).
414    ///
415    /// # Examples
416    ///
417    /// Basic usage:
418    ///
419    /// ```
420    /// use std::path::Path;
421    ///
422    /// use bstr::{B, BString};
423    ///
424    /// let path = Path::new("foo");
425    /// let bs = BString::from_path_lossy(path);
426    /// assert_eq!(bs, B("foo"));
427    /// ```
428    #[inline]
429    pub fn from_path_lossy<'a>(path: &'a Path) -> Cow<'a, BStr> {
430        BString::from_os_str_lossy(path.as_os_str())
431    }
432
433    /// Appends the given byte to the end of this byte string.
434    ///
435    /// # Examples
436    ///
437    /// Basic usage:
438    ///
439    /// ```
440    /// use bstr::BString;
441    ///
442    /// let mut s = BString::from("abc");
443    /// s.push_byte(b'\xE2');
444    /// s.push_byte(b'\x98');
445    /// s.push_byte(b'\x83');
446    /// assert_eq!("abc☃", s);
447    /// ```
448    #[inline]
449    pub fn push_byte(&mut self, byte: u8) {
450        self.bytes.push(byte);
451    }
452
453    /// Appends the given `char` to the end of this byte string.
454    ///
455    /// # Examples
456    ///
457    /// Basic usage:
458    ///
459    /// ```
460    /// use bstr::BString;
461    ///
462    /// let mut s = BString::from("abc");
463    /// s.push_char('1');
464    /// s.push_char('2');
465    /// s.push_char('3');
466    /// assert_eq!("abc123", s);
467    /// ```
468    #[inline]
469    pub fn push_char(&mut self, ch: char) {
470        if ch.len_utf8() == 1 {
471            self.bytes.push(ch as u8);
472            return;
473        }
474        self.bytes.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes());
475    }
476
477    /// Appends the given slice to the end of this byte string. This accepts
478    /// any type that be converted to a `&[u8]`. This includes, but is not
479    /// limited to, `&str`, `&BStr`, and of course, `&[u8]` itself.
480    ///
481    /// # Examples
482    ///
483    /// Basic usage:
484    ///
485    /// ```
486    /// use bstr::BString;
487    ///
488    /// let mut s = BString::from("abc");
489    /// s.push(b"123");
490    /// assert_eq!("abc123", s);
491    /// ```
492    #[inline]
493    pub fn push<B: AsRef<[u8]>>(&mut self, bytes: B) {
494        self.bytes.extend_from_slice(bytes.as_ref());
495    }
496
497    /// Extracts a byte string slice containing the entire `BString`.
498    ///
499    /// # Examples
500    ///
501    /// Basic usage:
502    ///
503    /// ```
504    /// use bstr::{BStr, BString};
505    ///
506    /// let s = BString::from("foo");
507    ///
508    /// assert_eq!(BStr::new("foo"), s.as_bstr());
509    /// ```
510    #[inline]
511    pub fn as_bstr(&self) -> &BStr {
512        BStr::from_bytes(&self.bytes)
513    }
514
515    /// Returns this `BString` as a borrowed byte vector.
516    ///
517    /// # Examples
518    ///
519    /// Basic usage:
520    ///
521    /// ```
522    /// use bstr::BString;
523    ///
524    /// let bs = BString::from("ab");
525    /// assert!(bs.as_vec().capacity() >= 2);
526    /// ```
527    #[inline]
528    pub fn as_vec(&self) -> &Vec<u8> {
529        &self.bytes
530    }
531
532    /// Converts a `BString` into a mutable string slice.
533    ///
534    /// # Examples
535    ///
536    /// Basic usage:
537    ///
538    /// ```
539    /// use bstr::BString;
540    ///
541    /// let mut s = BString::from("foobar");
542    /// let s_mut_str = s.as_mut_bstr();
543    ///
544    /// s_mut_str[0] = b'F';
545    ///
546    /// assert_eq!("Foobar", s_mut_str);
547    /// ```
548    #[inline]
549    pub fn as_mut_bstr(&mut self) -> &mut BStr {
550        BStr::from_bytes_mut(&mut self.bytes)
551    }
552
553    /// Returns this `BString` as a mutable byte vector.
554    ///
555    /// # Examples
556    ///
557    /// Basic usage:
558    ///
559    /// ```
560    /// use bstr::BString;
561    ///
562    /// let mut bs = BString::from("ab");
563    /// bs.as_mut_vec().push(b'c');
564    /// assert_eq!("abc", bs);
565    /// ```
566    #[inline]
567    pub fn as_mut_vec(&mut self) -> &mut Vec<u8> {
568        &mut self.bytes
569    }
570
571    /// Converts a `BString` into a byte vector.
572    ///
573    /// This consumes the `BString`, and thus the contents are not copied.
574    ///
575    /// # Examples
576    ///
577    /// Basic usage:
578    ///
579    /// ```
580    /// use bstr::BString;
581    ///
582    /// let s = BString::from("hello");
583    /// let bytes = s.into_vec();
584    ///
585    /// assert_eq!(vec![104, 101, 108, 108, 111], &bytes[..]);
586    /// ```
587    #[inline]
588    pub fn into_vec(self) -> Vec<u8> {
589        self.bytes
590    }
591
592    /// Converts a `BString` into a `String` if and only if this byte string is
593    /// valid UTF-8.
594    ///
595    /// If it is not valid UTF-8, then the error `std::string::FromUtf8Error`
596    /// is returned. (This error can be used to examine why UTF-8 validation
597    /// failed, or to regain the original byte string.)
598    ///
599    /// # Examples
600    ///
601    /// Basic usage:
602    ///
603    /// ```
604    /// use bstr::BString;
605    ///
606    /// # fn example() -> Result<(), ::bstr::FromUtf8Error> {
607    /// let bytes = BString::from("hello");
608    /// let string = bytes.into_string()?;
609    ///
610    /// assert_eq!("hello", string);
611    /// # Ok(()) }; example().unwrap()
612    /// ```
613    ///
614    /// If this byte string is not valid UTF-8, then an error will be returned.
615    /// That error can then be used to inspect the location at which invalid
616    /// UTF-8 was found, or to regain the original byte string:
617    ///
618    /// ```
619    /// use bstr::{B, BString};
620    ///
621    /// let bytes = BString::from_slice(b"foo\xFFbar");
622    /// let err = bytes.into_string().unwrap_err();
623    ///
624    /// assert_eq!(err.utf8_error().valid_up_to(), 3);
625    /// assert_eq!(err.utf8_error().error_len(), Some(1));
626    ///
627    /// // At no point in this example is an allocation performed.
628    /// let bytes = BString::from(err.into_bstring());
629    /// assert_eq!(bytes, B(b"foo\xFFbar"));
630    /// ```
631    #[inline]
632    pub fn into_string(self) -> Result<String, FromUtf8Error> {
633        match utf8::validate(self.as_bytes()) {
634            Err(err) => {
635                Err(FromUtf8Error { original: self, err: err })
636            }
637            Ok(()) => {
638                // SAFETY: This is safe because of the guarantees provided by
639                // utf8::validate.
640                unsafe { Ok(self.into_string_unchecked()) }
641            }
642        }
643    }
644
645    /// Lossily converts a `BString` into a `String`. If this byte string
646    /// contains invalid UTF-8, then the invalid bytes are replaced with the
647    /// Unicode replacement codepoint.
648    ///
649    /// # Examples
650    ///
651    /// Basic usage:
652    ///
653    /// ```
654    /// use bstr::BString;
655    ///
656    /// let bytes = BString::from_slice(b"foo\xFFbar");
657    /// let string = bytes.into_string_lossy();
658    /// assert_eq!(string, "foo\u{FFFD}bar");
659    /// ```
660    #[inline]
661    pub fn into_string_lossy(self) -> String {
662        self.to_string()
663    }
664
665    /// Unsafely convert this byte string into a `String`, without checking for
666    /// valid UTF-8.
667    ///
668    /// # Safety
669    ///
670    /// Callers *must* ensure that this byte string is valid UTF-8 before
671    /// calling this method. Converting a byte string into a `String` that is
672    /// not valid UTF-8 is considered undefined behavior.
673    ///
674    /// This routine is useful in performance sensitive contexts where the
675    /// UTF-8 validity of the byte string is already known and it is
676    /// undesirable to pay the cost of an additional UTF-8 validation check
677    /// that [`into_string`](#method.into_string) performs.
678    ///
679    /// # Examples
680    ///
681    /// Basic usage:
682    ///
683    /// ```
684    /// use bstr::BString;
685    ///
686    /// // SAFETY: This is safe because string literals are guaranteed to be
687    /// // valid UTF-8 by the Rust compiler.
688    /// let s = unsafe { BString::from("☃βツ").into_string_unchecked() };
689    /// assert_eq!("☃βツ", s);
690    /// ```
691    pub unsafe fn into_string_unchecked(self) -> String {
692        String::from_utf8_unchecked(self.into_vec())
693    }
694
695    /// Converts this byte string into an OS string, in place.
696    ///
697    /// On Unix, this always succeeds and is zero cost. On non-Unix systems,
698    /// this returns the original byte string if it is not valid UTF-8.
699    ///
700    /// # Examples
701    ///
702    /// Basic usage:
703    ///
704    /// ```
705    /// use std::ffi::OsStr;
706    ///
707    /// use bstr::BString;
708    ///
709    /// let bs = BString::from("foo");
710    /// let os_str = bs.into_os_string().expect("should be valid UTF-8");
711    /// assert_eq!(os_str, OsStr::new("foo"));
712    /// ```
713    #[inline]
714    pub fn into_os_string(self) -> Result<OsString, BString> {
715        self.into_os_string_imp()
716    }
717
718    #[cfg(unix)]
719    fn into_os_string_imp(self) -> Result<OsString, BString> {
720        use std::os::unix::ffi::OsStringExt;
721
722        Ok(OsString::from_vec(self.into_vec()))
723    }
724
725    #[cfg(not(unix))]
726    fn into_os_string_imp(self) -> Result<OsString, BString> {
727        match self.into_string() {
728            Ok(s) => Ok(OsString::from(s)),
729            Err(err) => Err(err.into_bstring()),
730        }
731    }
732
733    /// Lossily converts this byte string into an OS string, in place.
734    ///
735    /// On Unix, this always succeeds and is zero cost. On non-Unix systems,
736    /// this will perform a UTF-8 check and lossily convert this byte string
737    /// into valid UTF-8 using the Unicode replacement codepoint.
738    ///
739    /// Note that this can prevent the correct roundtripping of file paths on
740    /// non-Unix systems such as Windows, where file paths are an arbitrary
741    /// sequence of 16-bit integers.
742    ///
743    /// # Examples
744    ///
745    /// Basic usage:
746    ///
747    /// ```
748    /// use bstr::BString;
749    ///
750    /// let bs = BString::from_slice(b"foo\xFFbar");
751    /// let os_str = bs.into_os_string_lossy();
752    /// assert_eq!(os_str.to_string_lossy(), "foo\u{FFFD}bar");
753    /// ```
754    #[inline]
755    pub fn into_os_string_lossy(self) -> OsString {
756        self.into_os_string_lossy_imp()
757    }
758
759    #[cfg(unix)]
760    fn into_os_string_lossy_imp(self) -> OsString {
761        use std::os::unix::ffi::OsStringExt;
762
763        OsString::from_vec(self.into_vec())
764    }
765
766    #[cfg(not(unix))]
767    fn into_os_string_lossy_imp(self) -> OsString {
768        OsString::from(self.into_string_lossy())
769    }
770
771    /// Converts this byte string into an owned file path, in place.
772    ///
773    /// On Unix, this always succeeds and is zero cost. On non-Unix systems,
774    /// this returns the original byte string if it is not valid UTF-8.
775    ///
776    /// # Examples
777    ///
778    /// Basic usage:
779    ///
780    /// ```
781    /// use bstr::BString;
782    ///
783    /// let bs = BString::from("foo");
784    /// let path = bs.into_path_buf().expect("should be valid UTF-8");
785    /// assert_eq!(path.as_os_str(), "foo");
786    /// ```
787    #[inline]
788    pub fn into_path_buf(self) -> Result<PathBuf, BString> {
789        self.into_os_string().map(PathBuf::from)
790    }
791
792    /// Lossily converts this byte string into an owned file path, in place.
793    ///
794    /// On Unix, this always succeeds and is zero cost. On non-Unix systems,
795    /// this will perform a UTF-8 check and lossily convert this byte string
796    /// into valid UTF-8 using the Unicode replacement codepoint.
797    ///
798    /// Note that this can prevent the correct roundtripping of file paths on
799    /// non-Unix systems such as Windows, where file paths are an arbitrary
800    /// sequence of 16-bit integers.
801    ///
802    /// # Examples
803    ///
804    /// Basic usage:
805    ///
806    /// ```
807    /// use bstr::BString;
808    ///
809    /// let bs = BString::from_slice(b"foo\xFFbar");
810    /// let path = bs.into_path_buf_lossy();
811    /// assert_eq!(path.to_string_lossy(), "foo\u{FFFD}bar");
812    /// ```
813    #[inline]
814    pub fn into_path_buf_lossy(self) -> PathBuf {
815        PathBuf::from(self.into_os_string_lossy())
816    }
817
818    /// Converts this `BString` into a `Box<BStr>`.
819    ///
820    /// This will drop any excess capacity.
821    ///
822    /// # Examples
823    ///
824    /// Basic usage:
825    ///
826    /// ```
827    /// use bstr::BString;
828    ///
829    /// let s = BString::from("foobar");
830    /// let b = s.into_boxed_bstr();
831    /// assert_eq!(6, b.len());
832    /// ```
833    #[inline]
834    pub fn into_boxed_bstr(self) -> Box<BStr> {
835        unsafe {
836            let slice = self.bytes.into_boxed_slice();
837            Box::from_raw(Box::into_raw(slice) as *mut BStr)
838        }
839    }
840
841    /// Returns this byte string's capacity, in bytes.
842    ///
843    /// # Examples
844    ///
845    /// Basic usage:
846    ///
847    /// ```
848    /// use bstr::BString;
849    ///
850    /// let s = BString::with_capacity(10);
851    /// assert_eq!(10, s.capacity());
852    /// ```
853    #[inline]
854    pub fn capacity(&self) -> usize {
855        self.bytes.capacity()
856    }
857
858    /// Truncates this byte string, removing all contents.
859    ///
860    /// The resulting byte string will always have length `0`, but its capacity
861    /// remains unchanged.
862    #[inline]
863    pub fn clear(&mut self) {
864        self.bytes.clear();
865    }
866
867    /// Ensures that this `BString`'s capacity is at least `additional`
868    /// bytes larger than its length.
869    ///
870    /// The capacity may be increased by more than `additional` bytes if it
871    /// chooses, to prevent frequent reallocations.
872    ///
873    /// If you do not want this "at least" behavior, use the
874    /// [`reserve_exact`](#method.reserve_exact) method instead.
875    ///
876    /// # Panics
877    ///
878    /// Panics if the new capacity overflows `usize`.
879    ///
880    /// # Examples
881    ///
882    /// Basic usage:
883    ///
884    /// ```
885    /// use bstr::BString;
886    ///
887    /// let mut s = BString::new();
888    /// s.reserve(10);
889    /// assert!(s.capacity() >= 10);
890    /// ```
891    #[inline]
892    pub fn reserve(&mut self, additional: usize) {
893        self.bytes.reserve(additional);
894    }
895
896    /// Ensures that this `BString`'s capacity is exactly `additional`
897    /// bytes larger than its length.
898    ///
899    /// Consider using the [`reserve`](#method.reserve) method unless you
900    /// absolutely know better than the allocator.
901    ///
902    /// # Panics
903    ///
904    /// Panics if the new capacity overflows `usize`.
905    ///
906    /// # Examples
907    ///
908    /// Basic usage:
909    ///
910    /// ```
911    /// use bstr::BString;
912    ///
913    /// let mut s = BString::new();
914    /// s.reserve_exact(10);
915    /// assert!(s.capacity() >= 10);
916    /// ```
917    #[inline]
918    pub fn reserve_exact(&mut self, additional: usize) {
919        self.bytes.reserve_exact(additional);
920    }
921
922    /// Shrinks the capacity of this `BString` to match its length.
923    ///
924    /// Examples
925    ///
926    /// Basic usage:
927    ///
928    /// ```
929    /// use bstr::BString;
930    ///
931    /// let mut s = BString::from("foo");
932    /// s.reserve(10);
933    /// assert!(s.capacity() >= 10);
934    /// s.shrink_to_fit();
935    /// assert_eq!(3, s.capacity());
936    /// ```
937    #[inline]
938    pub fn shrink_to_fit(&mut self) {
939        self.bytes.shrink_to_fit();
940    }
941
942    /// Shortens this `BString` to the specified length, in bytes.
943    ///
944    /// If `new_len` is greater than or equal to this byte string's current
945    /// length, then this has no effect.
946    ///
947    /// Note that this does _not_ panic if the result is not on a valid
948    /// `char` boundary.
949    ///
950    /// # Examples
951    ///
952    /// Basic usage:
953    ///
954    /// ```
955    /// use bstr::BString;
956    ///
957    /// let mut s = BString::from("foobar");
958    /// s.truncate(3);
959    /// assert_eq!("foo", s);
960    /// ```
961    #[inline]
962    pub fn truncate(&mut self, new_len: usize) {
963        if new_len < self.len() {
964            self.bytes.truncate(new_len);
965        }
966    }
967
968    /// Resizes this byte string in place so that the length of this byte
969    /// string is equivalent to `new_len`.
970    ///
971    /// If `new_len` is greater than the length of this byte string, then
972    /// the byte string is extended by the difference, which each additional
973    /// byte filled with the given value. If `new_len` is less than the length
974    /// of this byte string, then it is simply truncated.
975    ///
976    /// # Examples
977    ///
978    /// Basic usage:
979    ///
980    /// ```
981    /// use bstr::BString;
982    ///
983    /// let mut s = BString::from("f");
984    /// s.resize(3, b'o');
985    /// assert_eq!(s, "foo");
986    /// s.resize(1, b'o');
987    /// assert_eq!(s, "f");
988    /// ```
989    #[inline]
990    pub fn resize(&mut self, new_len: usize, value: u8) {
991        self.bytes.resize(new_len, value);
992    }
993
994    /// Removes the last codepoint from this `BString` and returns it.
995    ///
996    /// If this byte string is empty, then `None` is returned. If the last
997    /// bytes of this byte string do not correspond to a valid UTF-8 code unit
998    /// sequence, then the Unicode replacement codepoint is yielded instead in
999    /// accordance with the
1000    /// [replacement codepoint substitution policy](index.html#handling-of-invalid-utf8-8).
1001    ///
1002    /// # Examples
1003    ///
1004    /// Basic usage:
1005    ///
1006    /// ```
1007    /// use bstr::BString;
1008    ///
1009    /// let mut s = BString::from("foo");
1010    /// assert_eq!(s.pop_char(), Some('o'));
1011    /// assert_eq!(s.pop_char(), Some('o'));
1012    /// assert_eq!(s.pop_char(), Some('f'));
1013    /// assert_eq!(s.pop_char(), None);
1014    /// ```
1015    ///
1016    /// This shows the replacement codepoint substitution policy. Note that
1017    /// the first pop yields a replacement codepoint but actually removes two
1018    /// bytes. This is in contrast with subsequent pops when encountering
1019    /// `\xFF` since `\xFF` is never a valid prefix for any valid UTF-8
1020    /// code unit sequence.
1021    ///
1022    /// ```
1023    /// use bstr::BString;
1024    ///
1025    /// let mut s = BString::from_slice(b"f\xFF\xFF\xFFoo\xE2\x98");
1026    /// assert_eq!(s.pop_char(), Some('\u{FFFD}'));
1027    /// assert_eq!(s.pop_char(), Some('o'));
1028    /// assert_eq!(s.pop_char(), Some('o'));
1029    /// assert_eq!(s.pop_char(), Some('\u{FFFD}'));
1030    /// assert_eq!(s.pop_char(), Some('\u{FFFD}'));
1031    /// assert_eq!(s.pop_char(), Some('\u{FFFD}'));
1032    /// assert_eq!(s.pop_char(), Some('f'));
1033    /// assert_eq!(s.pop_char(), None);
1034    /// ```
1035    #[inline]
1036    pub fn pop_char(&mut self) -> Option<char> {
1037        let (ch, size) = utf8::decode_last_lossy(self.as_bytes());
1038        if size == 0 {
1039            return None;
1040        }
1041        let new_len = self.len() - size;
1042        self.truncate(new_len);
1043        Some(ch)
1044    }
1045
1046    /// Removes the last byte from this `BString` and returns it.
1047    ///
1048    /// If this byte string is empty, then `None` is returned.
1049    ///
1050    /// Note that if the last codepoint in this byte string is not ASCII, then
1051    /// removing the last byte could make this byte string contain invalid
1052    /// UTF-8.
1053    ///
1054    /// # Examples
1055    ///
1056    /// Basic usage:
1057    ///
1058    /// ```
1059    /// use bstr::BString;
1060    ///
1061    /// let mut s = BString::from("foo");
1062    /// assert_eq!(s.pop_byte(), Some(b'o'));
1063    /// assert_eq!(s.pop_byte(), Some(b'o'));
1064    /// assert_eq!(s.pop_byte(), Some(b'f'));
1065    /// assert_eq!(s.pop_byte(), None);
1066    /// ```
1067    #[inline]
1068    pub fn pop_byte(&mut self) -> Option<u8> {
1069        self.bytes.pop()
1070    }
1071
1072    /// **DEPRECATED**: Use
1073    /// [`pop_char`](struct.BString.html#method.pop_char)
1074    /// or
1075    /// [`pop_byte`](struct.BString.html#method.pop_byte)
1076    /// instead.
1077    ///
1078    /// Removes the last codepoint from this `BString` and returns it.
1079    ///
1080    /// If this byte string is empty, then `None` is returned. If the last
1081    /// bytes of this byte string do not correspond to a valid UTF-8 code unit
1082    /// sequence, then the Unicode replacement codepoint is yielded instead in
1083    /// accordance with the
1084    /// [replacement codepoint substitution policy](index.html#handling-of-invalid-utf8-8).
1085    ///
1086    /// # Examples
1087    ///
1088    /// Basic usage:
1089    ///
1090    /// ```
1091    /// use bstr::BString;
1092    ///
1093    /// let mut s = BString::from("foo");
1094    /// assert_eq!(s.pop(), Some('o'));
1095    /// assert_eq!(s.pop(), Some('o'));
1096    /// assert_eq!(s.pop(), Some('f'));
1097    /// assert_eq!(s.pop(), None);
1098    /// ```
1099    ///
1100    /// This shows the replacement codepoint substitution policy. Note that
1101    /// the first pop yields a replacement codepoint but actually removes two
1102    /// bytes. This is in contrast with subsequent pops when encountering
1103    /// `\xFF` since `\xFF` is never a valid prefix for any valid UTF-8
1104    /// code unit sequence.
1105    ///
1106    /// ```
1107    /// use bstr::BString;
1108    ///
1109    /// let mut s = BString::from_slice(b"f\xFF\xFF\xFFoo\xE2\x98");
1110    /// assert_eq!(s.pop(), Some('\u{FFFD}'));
1111    /// assert_eq!(s.pop(), Some('o'));
1112    /// assert_eq!(s.pop(), Some('o'));
1113    /// assert_eq!(s.pop(), Some('\u{FFFD}'));
1114    /// assert_eq!(s.pop(), Some('\u{FFFD}'));
1115    /// assert_eq!(s.pop(), Some('\u{FFFD}'));
1116    /// assert_eq!(s.pop(), Some('f'));
1117    /// assert_eq!(s.pop(), None);
1118    /// ```
1119    #[deprecated(since = "0.1.1", note = "use pop_char or pop_byte instead")]
1120    #[inline]
1121    pub fn pop(&mut self) -> Option<char> {
1122        self.pop_char()
1123    }
1124
1125    /// Removes a `char` from this `BString` at the given byte position and
1126    /// returns it.
1127    ///
1128    /// If the bytes at the given position do not lead to a valid UTF-8 code
1129    /// unit sequence, then a
1130    /// [replacement codepoint is returned instead](index.html#handling-of-invalid-utf8-8).
1131    ///
1132    /// # Panics
1133    ///
1134    /// Panics if `at` is larger than or equal to this byte string's length.
1135    ///
1136    /// # Examples
1137    ///
1138    /// Basic usage:
1139    ///
1140    /// ```
1141    /// use bstr::BString;
1142    ///
1143    /// let mut s = BString::from("foo☃bar");
1144    /// assert_eq!('☃', s.remove(3));
1145    /// assert_eq!("foobar", s);
1146    /// ```
1147    ///
1148    /// This example shows how the Unicode replacement codepoint policy is
1149    /// used:
1150    ///
1151    /// ```
1152    /// use bstr::BString;
1153    ///
1154    /// let mut s = BString::from_slice(b"foo\xFFbar");
1155    /// assert_eq!('\u{FFFD}', s.remove(3));
1156    /// assert_eq!("foobar", s);
1157    /// ```
1158    #[inline]
1159    pub fn remove(&mut self, at: usize) -> char {
1160        let (ch, size) = utf8::decode_lossy(self[at..].as_bytes());
1161        assert!(size > 0, "expected {} to be less than {}", at, self.len());
1162        self.bytes.drain(at..at + size);
1163        ch
1164    }
1165
1166    /// Inserts the given codepoint into this `BString` at a particular byte
1167    /// position.
1168    ///
1169    /// This is an `O(n)` operation as it may copy a number of elements in this
1170    /// byte string proportional to its length.
1171    ///
1172    /// # Panics
1173    ///
1174    /// Panics if `at` is larger than the byte string's length.
1175    ///
1176    /// # Examples
1177    ///
1178    /// Basic usage:
1179    ///
1180    /// ```
1181    /// use bstr::BString;
1182    ///
1183    /// let mut s = BString::from("foobar");
1184    /// s.insert_char(3, '☃');
1185    /// assert_eq!("foo☃bar", s);
1186    /// ```
1187    #[inline]
1188    pub fn insert_char(&mut self, at: usize, ch: char) {
1189        self.insert(at, ch.encode_utf8(&mut [0; 4]).as_bytes());
1190    }
1191
1192    /// Inserts the given byte string into this byte string at a particular
1193    /// byte position.
1194    ///
1195    /// This is an `O(n)` operation as it may copy a number of elements in this
1196    /// byte string proportional to its length.
1197    ///
1198    /// Note that the type parameter `B` on this method means that it can
1199    /// accept anything that can be cheaply converted to a `&[u8]`. This
1200    /// includes, but is not limited to, `&str`, `&BStr` and `&[u8]` itself.
1201    ///
1202    /// # Panics
1203    ///
1204    /// Panics if `at` is larger than the byte string's length.
1205    ///
1206    /// # Examples
1207    ///
1208    /// Basic usage:
1209    ///
1210    /// ```
1211    /// use bstr::BString;
1212    ///
1213    /// let mut s = BString::from("foobar");
1214    /// s.insert(3, "☃☃☃");
1215    /// assert_eq!("foo☃☃☃bar", s);
1216    /// ```
1217    #[inline]
1218    pub fn insert<B: AsRef<[u8]>>(&mut self, at: usize, bytes: B) {
1219        assert!(at <= self.len(), "expected {} to be <= {}", at, self.len());
1220
1221        let bytes = bytes.as_ref();
1222        let len = self.len();
1223
1224        // SAFETY: We'd like to efficiently splice in the given bytes into
1225        // this byte string. Since we are only working with `u8` elements here,
1226        // we only need to consider whether our bounds are correct and whether
1227        // our byte string has enough space.
1228        self.reserve(bytes.len());
1229        unsafe {
1230            // Shift bytes after `at` over by the length of `bytes` to make
1231            // room for it. This requires referencing two regions of memory
1232            // that may overlap, so we use ptr::copy.
1233            ptr::copy(
1234                self.bytes.as_ptr().add(at),
1235                self.bytes.as_mut_ptr().add(at + bytes.len()),
1236                len - at,
1237            );
1238            // Now copy the bytes given into the room we made above. In this
1239            // case, we know that the given bytes cannot possibly overlap
1240            // with this byte string since we have a mutable borrow of the
1241            // latter. Thus, we can use a nonoverlapping copy.
1242            ptr::copy_nonoverlapping(
1243                bytes.as_ptr(),
1244                self.bytes.as_mut_ptr().add(at),
1245                bytes.len(),
1246            );
1247            self.bytes.set_len(len + bytes.len());
1248        }
1249    }
1250
1251    /// Splits this `BString` into two separate byte strings at the given
1252    /// index.
1253    ///
1254    /// This returns a newly allocated `BString`, while `self` retans bytes
1255    /// `[0, at)` and the returned `BString` contains bytes `[at, len)`.
1256    ///
1257    /// The capacity of `self` does not change.
1258    ///
1259    /// # Panics
1260    ///
1261    /// Panics if `at` is beyond the end of this byte string.
1262    ///
1263    /// # Examples
1264    ///
1265    /// Basic usage:
1266    ///
1267    /// ```
1268    /// use bstr::BString;
1269    ///
1270    /// let mut s = BString::from("foobar");
1271    /// let bar = s.split_off(3);
1272    /// assert_eq!(s, "foo");
1273    /// assert_eq!(bar, "bar");
1274    /// ```
1275    #[inline]
1276    pub fn split_off(&mut self, at: usize) -> BString {
1277        BString::from(self.bytes.split_off(at))
1278    }
1279
1280    /// Removes the specified range in this byte string and replaces it with
1281    /// the given bytes. The given bytes do not need to have the same length
1282    /// as the range provided.
1283    ///
1284    /// # Panics
1285    ///
1286    /// Panics if the given range is invalid.
1287    ///
1288    /// # Examples
1289    ///
1290    /// Basic usage:
1291    ///
1292    /// ```
1293    /// use bstr::BString;
1294    ///
1295    /// let mut s = BString::from("foobar");
1296    /// s.replace_range(2..4, "xxxxx");
1297    /// assert_eq!(s, "foxxxxxar");
1298    /// ```
1299    #[inline]
1300    pub fn replace_range<R, B>(
1301        &mut self,
1302        range: R,
1303        replace_with: B,
1304    ) where R: ops::RangeBounds<usize>,
1305            B: AsRef<[u8]>
1306    {
1307        self.bytes.splice(range, replace_with.as_ref().iter().cloned());
1308    }
1309
1310    /// Creates a draining iterator that removes the specified range in this
1311    /// `BString` and yields each of the removed bytes.
1312    ///
1313    /// Note that the elements specified by the given range are removed
1314    /// regardless of whether the returned iterator is fully exhausted.
1315    ///
1316    /// Also note that is is unspecified how many bytes are removed from the
1317    /// `BString` if the `DrainBytes` iterator is leaked.
1318    ///
1319    /// # Panics
1320    ///
1321    /// Panics if the given range is not valid.
1322    ///
1323    /// # Examples
1324    ///
1325    /// Basic usage:
1326    ///
1327    /// ```
1328    /// use bstr::BString;
1329    ///
1330    /// let mut s = BString::from("foobar");
1331    /// {
1332    ///     let mut drainer = s.drain_bytes(2..4);
1333    ///     assert_eq!(drainer.next(), Some(b'o'));
1334    ///     assert_eq!(drainer.next(), Some(b'b'));
1335    ///     assert_eq!(drainer.next(), None);
1336    /// }
1337    /// assert_eq!(s, "foar");
1338    /// ```
1339    #[inline]
1340    pub fn drain_bytes<R>(
1341        &mut self,
1342        range: R,
1343    ) -> DrainBytes
1344    where R: ops::RangeBounds<usize>
1345    {
1346        DrainBytes { it: self.bytes.drain(range) }
1347    }
1348}
1349
1350/// A draining byte oriented iterator for `BString`.
1351///
1352/// This iterator is created by
1353/// [`BString::drain`](struct.BString.html#method.drain).
1354///
1355/// # Examples
1356///
1357/// Basic usage:
1358///
1359/// ```
1360/// use bstr::BString;
1361///
1362/// let mut s = BString::from("foobar");
1363/// {
1364///     let mut drainer = s.drain_bytes(2..4);
1365///     assert_eq!(drainer.next(), Some(b'o'));
1366///     assert_eq!(drainer.next(), Some(b'b'));
1367///     assert_eq!(drainer.next(), None);
1368/// }
1369/// assert_eq!(s, "foar");
1370/// ```
1371#[derive(Debug)]
1372pub struct DrainBytes<'a> {
1373    it: vec::Drain<'a, u8>,
1374}
1375
1376impl<'a> iter::FusedIterator for DrainBytes<'a> {}
1377
1378impl<'a> Iterator for DrainBytes<'a> {
1379    type Item = u8;
1380
1381    #[inline]
1382    fn next(&mut self) -> Option<u8> {
1383        self.it.next()
1384    }
1385}
1386
1387impl<'a> DoubleEndedIterator for DrainBytes<'a> {
1388    #[inline]
1389    fn next_back(&mut self) -> Option<u8> {
1390        self.it.next_back()
1391    }
1392}
1393
1394impl<'a> ExactSizeIterator for DrainBytes<'a> {
1395    #[inline]
1396    fn len(&self) -> usize {
1397        self.it.len()
1398    }
1399}
1400
1401/// An error that may occur when converting a `BString` to a `String`.
1402///
1403/// This error includes the original `BString` that failed to convert to a
1404/// `String`. This permits callers to recover the allocation used even if it
1405/// it not valid UTF-8.
1406///
1407/// # Examples
1408///
1409/// Basic usage:
1410///
1411/// ```
1412/// use bstr::{B, BString};
1413///
1414/// let bytes = BString::from_slice(b"foo\xFFbar");
1415/// let err = bytes.into_string().unwrap_err();
1416///
1417/// assert_eq!(err.utf8_error().valid_up_to(), 3);
1418/// assert_eq!(err.utf8_error().error_len(), Some(1));
1419///
1420/// // At no point in this example is an allocation performed.
1421/// let bytes = BString::from(err.into_bstring());
1422/// assert_eq!(bytes, B(b"foo\xFFbar"));
1423/// ```
1424#[derive(Debug, Eq, PartialEq)]
1425pub struct FromUtf8Error {
1426    original: BString,
1427    err: Utf8Error,
1428}
1429
1430impl FromUtf8Error {
1431    /// Return the original bytes as a slice that failed to convert to a
1432    /// `String`.
1433    ///
1434    /// # Examples
1435    ///
1436    /// Basic usage:
1437    ///
1438    /// ```
1439    /// use bstr::{B, BString};
1440    ///
1441    /// let bytes = BString::from_slice(b"foo\xFFbar");
1442    /// let err = bytes.into_string().unwrap_err();
1443    ///
1444    /// // At no point in this example is an allocation performed.
1445    /// assert_eq!(err.as_bstr(), B(b"foo\xFFbar"));
1446    /// ```
1447    #[inline]
1448    pub fn as_bstr(&self) -> &BStr {
1449        &self.original
1450    }
1451
1452    /// Consume this error and return the original byte string that failed to
1453    /// convert to a `String`.
1454    ///
1455    /// # Examples
1456    ///
1457    /// Basic usage:
1458    ///
1459    /// ```
1460    /// use bstr::{B, BString};
1461    ///
1462    /// let bytes = BString::from_slice(b"foo\xFFbar");
1463    /// let err = bytes.into_string().unwrap_err();
1464    /// let original = err.into_bstring();
1465    ///
1466    /// // At no point in this example is an allocation performed.
1467    /// assert_eq!(original, B(b"foo\xFFbar"));
1468    /// ```
1469    #[inline]
1470    pub fn into_bstring(self) -> BString {
1471        self.original
1472    }
1473
1474    /// Return the underlying UTF-8 error that occurred. This error provides
1475    /// information on the nature and location of the invalid UTF-8 detected.
1476    ///
1477    /// # Examples
1478    ///
1479    /// Basic usage:
1480    ///
1481    /// ```
1482    /// use bstr::{B, BString};
1483    ///
1484    /// let bytes = BString::from_slice(b"foo\xFFbar");
1485    /// let err = bytes.into_string().unwrap_err();
1486    ///
1487    /// assert_eq!(err.utf8_error().valid_up_to(), 3);
1488    /// assert_eq!(err.utf8_error().error_len(), Some(1));
1489    /// ```
1490    #[inline]
1491    pub fn utf8_error(&self) -> &Utf8Error {
1492        &self.err
1493    }
1494}
1495
1496impl error::Error for FromUtf8Error {
1497    #[inline]
1498    fn description(&self) -> &str { "invalid UTF-8 vector" }
1499}
1500
1501impl fmt::Display for FromUtf8Error {
1502    #[inline]
1503    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1504        write!(f, "{}", self.err)
1505    }
1506}
1507
1508#[cfg(test)]
1509mod tests {
1510    use bstr::B;
1511    use super::*;
1512
1513    #[test]
1514    fn insert() {
1515        let mut s = BString::new();
1516        s.insert(0, "foo");
1517        assert_eq!("foo", s);
1518
1519        let mut s = BString::from("a");
1520        s.insert(0, "foo");
1521        assert_eq!("fooa", s);
1522
1523        let mut s = BString::from("a");
1524        s.insert(1, "foo");
1525        assert_eq!("afoo", s);
1526
1527        let mut s = BString::from("foobar");
1528        s.insert(3, "quux");
1529        assert_eq!("fooquuxbar", s);
1530
1531        let mut s = BString::from("foobar");
1532        s.insert(3, "x");
1533        assert_eq!("fooxbar", s);
1534
1535        let mut s = BString::from("foobar");
1536        s.insert(0, "x");
1537        assert_eq!("xfoobar", s);
1538
1539        let mut s = BString::from("foobar");
1540        s.insert(6, "x");
1541        assert_eq!("foobarx", s);
1542
1543        let mut s = BString::from("foobar");
1544        s.insert(3, "quuxbazquux");
1545        assert_eq!("fooquuxbazquuxbar", s);
1546    }
1547
1548    #[test]
1549    #[should_panic]
1550    fn insert_fail1() {
1551        let mut s = BString::new();
1552        s.insert(1, "foo");
1553    }
1554
1555    #[test]
1556    #[should_panic]
1557    fn insert_fail2() {
1558        let mut s = BString::from("a");
1559        s.insert(2, "foo");
1560    }
1561
1562    #[test]
1563    #[should_panic]
1564    fn insert_fail3() {
1565        let mut s = BString::from("foobar");
1566        s.insert(7, "foo");
1567    }
1568
1569    #[test]
1570    fn collect() {
1571        let s: BString = vec!['a', 'b', 'c'].into_iter().collect();
1572        assert_eq!(s, "abc");
1573
1574        let s: BString = vec!["a", "b", "c"].into_iter().collect();
1575        assert_eq!(s, "abc");
1576
1577        let s: BString = vec![B("a"), B("b"), B("c")].into_iter().collect();
1578        assert_eq!(s, "abc");
1579    }
1580}