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}