1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! A UTF-8 encoded, growable string.
13 //! This module contains the [`String`] type and several error types that may
14 //! result from working with [`String`]s.
16 //! This module is a fork of the [`std::string`] module, that uses a bump allocator.
18 //! [`std::string`]: https://doc.rust-lang.org/std/string/index.html
22 //! You can create a new [`String`] from a string literal with [`String::from_str_in`]:
25 //! use bumpalo::{Bump, collections::String};
27 //! let b = Bump::new();
29 //! let s = String::from_str_in("world", &b);
32 //! [`String`]: struct.String.html
33 //! [`String::from_str_in`]: struct.String.html#method.from_str_in
35 //! If you have a vector of valid UTF-8 bytes, you can make a [`String`] out of
36 //! it. You can do the reverse too.
39 //! use bumpalo::{Bump, collections::String};
41 //! let b = Bump::new();
43 //! let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
45 //! // We know these bytes are valid, so we'll use `unwrap()`.
46 //! let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
48 //! assert_eq!("💖", sparkle_heart);
50 //! let bytes = sparkle_heart.into_bytes();
52 //! assert_eq!(bytes, [240, 159, 146, 150]);
55 use crate::collections
::str::lossy
;
56 use crate::collections
::vec
::Vec
;
58 use core
::borrow
::{Borrow, BorrowMut}
;
59 use core
::char::decode_utf16
;
62 use core
::iter
::FusedIterator
;
64 use core
::ops
::Bound
::{Excluded, Included, Unbounded}
;
65 use core
::ops
::{self, Add, AddAssign, Index, IndexMut, RangeBounds}
;
67 use core
::str::{self, Chars, Utf8Error}
;
68 use core_alloc
::borrow
::Cow
;
70 /// Like the [`format!`] macro, but for creating [`bumpalo::collections::String`]s.
72 /// [`format!`]: https://doc.rust-lang.org/std/macro.format.html
73 /// [`bumpalo::collections::String`]: collections/string/struct.String.html
78 /// use bumpalo::Bump;
80 /// let b = Bump::new();
82 /// let who = "World";
83 /// let s = bumpalo::format!(in &b, "Hello, {}!", who);
84 /// assert_eq!(s, "Hello, World!")
88 ( in $bump
:expr
, $fmt
:expr
, $
($args
:expr
),* ) => {{
89 use $
crate::core_alloc
::fmt
::Write
;
91 let mut s
= $
crate::collections
::String
::new_in(bump
);
92 let _
= write
!(&mut s
, $fmt
, $
($args
),*);
96 ( in $bump
:expr
, $fmt
:expr
, $
($args
:expr
,)* ) => {
97 $
crate::format
!(in $bump
, $fmt
, $
($args
),*)
101 /// A UTF-8 encoded, growable string.
103 /// The `String` type is the most common string type that has ownership over the
104 /// contents of the string. It has a close relationship with its borrowed
105 /// counterpart, the primitive [`str`].
107 /// [`str`]: https://doc.rust-lang.org/std/primitive.str.html
111 /// You can create a `String` from a literal string with [`String::from_str_in`]:
114 /// use bumpalo::{Bump, collections::String};
116 /// let b = Bump::new();
118 /// let hello = String::from_str_in("Hello, world!", &b);
121 /// You can append a [`char`] to a `String` with the [`push`] method, and
122 /// append a [`&str`] with the [`push_str`] method:
125 /// use bumpalo::{Bump, collections::String};
127 /// let b = Bump::new();
129 /// let mut hello = String::from_str_in("Hello, ", &b);
132 /// hello.push_str("orld!");
135 /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
136 /// [`push`]: #method.push
137 /// [`push_str`]: #method.push_str
139 /// If you have a vector of UTF-8 bytes, you can create a `String` from it with
140 /// the [`from_utf8`] method:
143 /// use bumpalo::{Bump, collections::String};
145 /// let b = Bump::new();
147 /// // some bytes, in a vector
148 /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
150 /// // We know these bytes are valid, so we'll use `unwrap()`.
151 /// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
153 /// assert_eq!("💖", sparkle_heart);
156 /// [`from_utf8`]: #method.from_utf8
160 /// `String`s implement <code>[`Deref`]<Target = [`str`]></code>, and so inherit all of [`str`]'s
161 /// methods. In addition, this means that you can pass a `String` to a
162 /// function which takes a [`&str`] by using an ampersand (`&`):
165 /// use bumpalo::{Bump, collections::String};
167 /// let b = Bump::new();
169 /// fn takes_str(s: &str) { }
171 /// let s = String::from_str_in("Hello", &b);
176 /// This will create a [`&str`] from the `String` and pass it in. This
177 /// conversion is very inexpensive, and so generally, functions will accept
178 /// [`&str`]s as arguments unless they need a `String` for some specific
181 /// In certain cases Rust doesn't have enough information to make this
182 /// conversion, known as [`Deref`] coercion. In the following example a string
183 /// slice [`&'a str`][`&str`] implements the trait `TraitExample`, and the function
184 /// `example_func` takes anything that implements the trait. In this case Rust
185 /// would need to make two implicit conversions, which Rust doesn't have the
186 /// means to do. For that reason, the following example will not compile.
188 /// ```compile_fail,E0277
189 /// use bumpalo::{Bump, collections::String};
191 /// trait TraitExample {}
193 /// impl<'a> TraitExample for &'a str {}
195 /// fn example_func<A: TraitExample>(example_arg: A) {}
197 /// let b = Bump::new();
198 /// let example_string = String::from_str_in("example_string", &b);
199 /// example_func(&example_string);
202 /// There are two options that would work instead. The first would be to
203 /// change the line `example_func(&example_string);` to
204 /// `example_func(example_string.as_str());`, using the method [`as_str()`]
205 /// to explicitly extract the string slice containing the string. The second
206 /// way changes `example_func(&example_string);` to
207 /// `example_func(&*example_string);`. In this case we are dereferencing a
208 /// `String` to a [`str`][`&str`], then referencing the [`str`][`&str`] back to
209 /// [`&str`]. The second way is more idiomatic, however both work to do the
210 /// conversion explicitly rather than relying on the implicit conversion.
214 /// A `String` is made up of three components: a pointer to some bytes, a
215 /// length, and a capacity. The pointer points to an internal buffer `String`
216 /// uses to store its data. The length is the number of bytes currently stored
217 /// in the buffer, and the capacity is the size of the buffer in bytes. As such,
218 /// the length will always be less than or equal to the capacity.
220 /// This buffer is always stored on the heap.
222 /// You can look at these with the [`as_ptr`], [`len`], and [`capacity`]
226 /// use bumpalo::{Bump, collections::String};
229 /// let b = Bump::new();
231 /// let mut story = String::from_str_in("Once upon a time...", &b);
233 /// let ptr = story.as_mut_ptr();
234 /// let len = story.len();
235 /// let capacity = story.capacity();
237 /// // story has nineteen bytes
238 /// assert_eq!(19, len);
240 /// // Now that we have our parts, we throw the story away.
241 /// mem::forget(story);
243 /// // We can re-build a String out of ptr, len, and capacity. This is all
244 /// // unsafe because we are responsible for making sure the components are
246 /// let s = unsafe { String::from_raw_parts_in(ptr, len, capacity, &b) } ;
248 /// assert_eq!(String::from_str_in("Once upon a time...", &b), s);
251 /// [`as_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_ptr
252 /// [`len`]: #method.len
253 /// [`capacity`]: #method.capacity
255 /// If a `String` has enough capacity, adding elements to it will not
256 /// re-allocate. For example, consider this program:
259 /// use bumpalo::{Bump, collections::String};
261 /// let b = Bump::new();
263 /// let mut s = String::new_in(&b);
265 /// println!("{}", s.capacity());
268 /// s.push_str("hello");
269 /// println!("{}", s.capacity());
273 /// This will output the following:
284 /// At first, we have no memory allocated at all, but as we append to the
285 /// string, it increases its capacity appropriately. If we instead use the
286 /// [`with_capacity_in`] method to allocate the correct capacity initially:
289 /// use bumpalo::{Bump, collections::String};
291 /// let b = Bump::new();
293 /// let mut s = String::with_capacity_in(25, &b);
295 /// println!("{}", s.capacity());
298 /// s.push_str("hello");
299 /// println!("{}", s.capacity());
303 /// [`with_capacity_in`]: #method.with_capacity_in
305 /// We end up with a different output:
316 /// Here, there's no need to allocate more memory inside the loop.
318 /// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
319 /// [`Deref`]: https://doc.rust-lang.org/std/ops/trait.Deref.html
320 /// [`as_str()`]: struct.String.html#method.as_str
321 #[derive(PartialOrd, Eq, Ord)]
322 pub struct String
<'bump
> {
326 /// A possible error value when converting a `String` from a UTF-8 byte vector.
328 /// This type is the error type for the [`from_utf8`] method on [`String`]. It
329 /// is designed in such a way to carefully avoid reallocations: the
330 /// [`into_bytes`] method will give back the byte vector that was used in the
331 /// conversion attempt.
333 /// [`from_utf8`]: struct.String.html#method.from_utf8
334 /// [`String`]: struct.String.html
335 /// [`into_bytes`]: struct.FromUtf8Error.html#method.into_bytes
337 /// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
338 /// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
339 /// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error`
340 /// through the [`utf8_error`] method.
342 /// [`Utf8Error`]: https://doc.rust-lang.org/std/str/struct.Utf8Error.html
343 /// [`std::str`]: https://doc.rust-lang.org/std/str/index.html
344 /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
345 /// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
346 /// [`utf8_error`]: #method.utf8_error
353 /// use bumpalo::{Bump, collections::String};
355 /// let b = Bump::new();
357 /// // some invalid bytes, in a vector
358 /// let bytes = bumpalo::vec![in &b; 0, 159];
360 /// let value = String::from_utf8(bytes);
362 /// assert!(value.is_err());
363 /// assert_eq!(bumpalo::vec![in &b; 0, 159], value.unwrap_err().into_bytes());
366 pub struct FromUtf8Error
<'bump
> {
367 bytes
: Vec
<'bump
, u8>,
371 /// A possible error value when converting a `String` from a UTF-16 byte slice.
373 /// This type is the error type for the [`from_utf16_in`] method on [`String`].
375 /// [`from_utf16_in`]: struct.String.html#method.from_utf16_in
376 /// [`String`]: struct.String.html
383 /// use bumpalo::{Bump, collections::String};
385 /// let b = Bump::new();
387 /// // 𝄞mu<invalid>ic
388 /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063];
390 /// assert!(String::from_utf16_in(v, &b).is_err());
393 pub struct FromUtf16Error(());
395 impl<'bump
> String
<'bump
> {
396 /// Creates a new empty `String`.
398 /// Given that the `String` is empty, this will not allocate any initial
399 /// buffer. While that means that this initial operation is very
400 /// inexpensive, it may cause excessive allocation later when you add
401 /// data. If you have an idea of how much data the `String` will hold,
402 /// consider the [`with_capacity_in`] method to prevent excessive
405 /// [`with_capacity_in`]: #method.with_capacity_in
412 /// use bumpalo::{Bump, collections::String};
414 /// let b = Bump::new();
416 /// let s = String::new_in(&b);
419 pub fn new_in(bump
: &'bump Bump
) -> String
<'bump
> {
421 vec
: Vec
::new_in(bump
),
425 /// Creates a new empty `String` with a particular capacity.
427 /// `String`s have an internal buffer to hold their data. The capacity is
428 /// the length of that buffer, and can be queried with the [`capacity`]
429 /// method. This method creates an empty `String`, but one with an initial
430 /// buffer that can hold `capacity` bytes. This is useful when you may be
431 /// appending a bunch of data to the `String`, reducing the number of
432 /// reallocations it needs to do.
434 /// [`capacity`]: #method.capacity
436 /// If the given capacity is `0`, no allocation will occur, and this method
437 /// is identical to the [`new_in`] method.
439 /// [`new_in`]: #method.new
446 /// use bumpalo::{Bump, collections::String};
448 /// let b = Bump::new();
450 /// let mut s = String::with_capacity_in(10, &b);
452 /// // The String contains no chars, even though it has capacity for more
453 /// assert_eq!(s.len(), 0);
455 /// // These are all done without reallocating...
456 /// let cap = s.capacity();
461 /// assert_eq!(s.capacity(), cap);
463 /// // ...but this may make the vector reallocate
467 pub fn with_capacity_in(capacity
: usize, bump
: &'bump Bump
) -> String
<'bump
> {
469 vec
: Vec
::with_capacity_in(capacity
, bump
),
473 /// Converts a vector of bytes to a `String`.
475 /// A string (`String`) is made of bytes ([`u8`]), and a vector of bytes
476 /// ([`Vec<u8>`]) is made of bytes, so this function converts between the
477 /// two. Not all byte slices are valid `String`s, however: `String`
478 /// requires that it is valid UTF-8. `from_utf8()` checks to ensure that
479 /// the bytes are valid UTF-8, and then does the conversion.
481 /// If you are sure that the byte slice is valid UTF-8, and you don't want
482 /// to incur the overhead of the validity check, there is an unsafe version
483 /// of this function, [`from_utf8_unchecked`], which has the same behavior
484 /// but skips the check.
486 /// This method will take care to not copy the vector, for efficiency's
489 /// If you need a [`&str`] instead of a `String`, consider
490 /// [`str::from_utf8`].
492 /// The inverse of this method is [`into_bytes`].
496 /// Returns [`Err`] if the slice is not UTF-8 with a description as to why the
497 /// provided bytes are not UTF-8. The vector you moved in is also included.
504 /// use bumpalo::{Bump, collections::String};
506 /// let b = Bump::new();
508 /// // some bytes, in a vector
509 /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
511 /// // We know these bytes are valid, so we'll use `unwrap()`.
512 /// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
514 /// assert_eq!("💖", sparkle_heart);
520 /// use bumpalo::{Bump, collections::String};
522 /// let b = Bump::new();
524 /// // some invalid bytes, in a vector
525 /// let sparkle_heart = bumpalo::vec![in &b; 0, 159, 146, 150];
527 /// assert!(String::from_utf8(sparkle_heart).is_err());
530 /// See the docs for [`FromUtf8Error`] for more details on what you can do
533 /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
534 /// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
535 /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
536 /// [`Vec<u8>`]: ../vec/struct.Vec.html
537 /// [`str::from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html
538 /// [`into_bytes`]: struct.String.html#method.into_bytes
539 /// [`FromUtf8Error`]: struct.FromUtf8Error.html
540 /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
542 pub fn from_utf8(vec
: Vec
<'bump
, u8>) -> Result
<String
<'bump
>, FromUtf8Error
<'bump
>> {
543 match str::from_utf8(&vec
) {
544 Ok(..) => Ok(String { vec }
),
545 Err(e
) => Err(FromUtf8Error
{
552 /// Converts a slice of bytes to a string, including invalid characters.
554 /// Strings are made of bytes ([`u8`]), and a slice of bytes
555 /// ([`&[u8]`][slice]) is made of bytes, so this function converts
556 /// between the two. Not all byte slices are valid strings, however: strings
557 /// are required to be valid UTF-8. During this conversion,
558 /// `from_utf8_lossy_in()` will replace any invalid UTF-8 sequences with
559 /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD], which looks like this: �
561 /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
562 /// [slice]: https://doc.rust-lang.org/std/primitive.slice.html
563 /// [U+FFFD]: https://doc.rust-lang.org/std/char/constant.REPLACEMENT_CHARACTER.html
565 /// If you are sure that the byte slice is valid UTF-8, and you don't want
566 /// to incur the overhead of the conversion, there is an unsafe version
567 /// of this function, [`from_utf8_unchecked`], which has the same behavior
568 /// but skips the checks.
570 /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
577 /// use bumpalo::{collections::String, Bump, vec};
579 /// let b = Bump::new();
581 /// // some bytes, in a vector
582 /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
584 /// let sparkle_heart = String::from_utf8_lossy_in(&sparkle_heart, &b);
586 /// assert_eq!("💖", sparkle_heart);
592 /// use bumpalo::{collections::String, Bump, vec};
594 /// let b = Bump::new();
596 /// // some invalid bytes
597 /// let input = b"Hello \xF0\x90\x80World";
598 /// let output = String::from_utf8_lossy_in(input, &b);
600 /// assert_eq!("Hello �World", output);
602 pub fn from_utf8_lossy_in(v
: &[u8], bump
: &'bump Bump
) -> String
<'bump
> {
603 let mut iter
= lossy
::Utf8Lossy
::from_bytes(v
).chunks();
605 let (first_valid
, first_broken
) = if let Some(chunk
) = iter
.next() {
606 let lossy
::Utf8LossyChunk { valid, broken }
= chunk
;
607 if valid
.len() == v
.len() {
608 debug_assert
!(broken
.is_empty());
610 return String
::from_utf8_unchecked(Vec
::from_iter_in(v
.iter().cloned(), bump
));
615 return String
::from_str_in("", bump
);
618 const REPLACEMENT
: &str = "\u{FFFD}";
620 let mut res
= String
::with_capacity_in(v
.len(), bump
);
621 res
.push_str(first_valid
);
622 if !first_broken
.is_empty() {
623 res
.push_str(REPLACEMENT
);
626 for lossy
::Utf8LossyChunk { valid, broken }
in iter
{
628 if !broken
.is_empty() {
629 res
.push_str(REPLACEMENT
);
636 /// Decode a UTF-16 encoded slice `v` into a `String`, returning [`Err`]
637 /// if `v` contains any invalid data.
639 /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
646 /// use bumpalo::{Bump, collections::String};
648 /// let b = Bump::new();
651 /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0x0069, 0x0063];
652 /// assert_eq!(String::from_str_in("𝄞music", &b), String::from_utf16_in(v, &b).unwrap());
654 /// // 𝄞mu<invalid>ic
655 /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063];
656 /// assert!(String::from_utf16_in(v, &b).is_err());
658 pub fn from_utf16_in(v
: &[u16], bump
: &'bump Bump
) -> Result
<String
<'bump
>, FromUtf16Error
> {
659 let mut ret
= String
::with_capacity_in(v
.len(), bump
);
660 for c
in decode_utf16(v
.iter().cloned()) {
664 return Err(FromUtf16Error(()));
670 /// Construct a new `String<'bump>` from a string slice.
675 /// use bumpalo::{Bump, collections::String};
677 /// let b = Bump::new();
679 /// let s = String::from_str_in("hello", &b);
680 /// assert_eq!(s, "hello");
682 pub fn from_str_in(s
: &str, bump
: &'bump Bump
) -> String
<'bump
> {
683 let mut t
= String
::with_capacity_in(s
.len(), bump
);
688 /// Construct a new `String<'bump>` from an iterator of `char`s.
693 /// use bumpalo::{Bump, collections::String};
695 /// let b = Bump::new();
697 /// let s = String::from_iter_in(['h', 'e', 'l', 'l', 'o'].iter().cloned(), &b);
698 /// assert_eq!(s, "hello");
700 pub fn from_iter_in
<I
: IntoIterator
<Item
= char>>(iter
: I
, bump
: &'bump Bump
) -> String
<'bump
> {
701 let mut s
= String
::new_in(bump
);
708 /// Creates a new `String` from a length, capacity, and pointer.
712 /// This is highly unsafe, due to the number of invariants that aren't
715 /// * The memory at `ptr` needs to have been previously allocated by the
716 /// same allocator the standard library uses.
717 /// * `length` needs to be less than or equal to `capacity`.
718 /// * `capacity` needs to be the correct value.
720 /// Violating these may cause problems like corrupting the allocator's
721 /// internal data structures.
723 /// The ownership of `ptr` is effectively transferred to the
724 /// `String` which may then deallocate, reallocate or change the
725 /// contents of memory pointed to by the pointer at will. Ensure
726 /// that nothing else uses the pointer after calling this
734 /// use bumpalo::{Bump, collections::String};
737 /// let b = Bump::new();
740 /// let mut s = String::from_str_in("hello", &b);
741 /// let ptr = s.as_mut_ptr();
742 /// let len = s.len();
743 /// let capacity = s.capacity();
747 /// let s = String::from_raw_parts_in(ptr, len, capacity, &b);
749 /// assert_eq!(s, "hello");
753 pub unsafe fn from_raw_parts_in(
760 vec
: Vec
::from_raw_parts_in(buf
, length
, capacity
, bump
),
764 /// Converts a vector of bytes to a `String` without checking that the
765 /// string contains valid UTF-8.
767 /// See the safe version, [`from_utf8`], for more details.
769 /// [`from_utf8`]: struct.String.html#method.from_utf8
773 /// This function is unsafe because it does not check that the bytes passed
774 /// to it are valid UTF-8. If this constraint is violated, it may cause
775 /// memory unsafety issues with future users of the `String`,
776 /// as it is assumed that `String`s are valid UTF-8.
783 /// use bumpalo::{Bump, collections::String};
785 /// let b = Bump::new();
787 /// // some bytes, in a vector
788 /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
790 /// let sparkle_heart = unsafe {
791 /// String::from_utf8_unchecked(sparkle_heart)
794 /// assert_eq!("💖", sparkle_heart);
797 pub unsafe fn from_utf8_unchecked(bytes
: Vec
<'bump
, u8>) -> String
<'bump
> {
798 String { vec: bytes }
801 /// Returns a shared reference to the allocator backing this `String`.
806 /// use bumpalo::{Bump, collections::String};
808 /// // uses the same allocator as the provided `String`
809 /// fn copy_string<'bump>(s: &String<'bump>) -> &'bump str {
810 /// s.bump().alloc_str(s.as_str())
815 pub fn bump(&self) -> &'bump Bump
{
819 /// Converts a `String` into a byte vector.
821 /// This consumes the `String`, so we do not need to copy its contents.
828 /// use bumpalo::{Bump, collections::String};
830 /// let b = Bump::new();
832 /// let s = String::from_str_in("hello", &b);
834 /// assert_eq!(s.into_bytes(), [104, 101, 108, 108, 111]);
837 pub fn into_bytes(self) -> Vec
<'bump
, u8> {
841 /// Convert this `String<'bump>` into a `&'bump str`. This is analogous to
842 /// [`std::string::String::into_boxed_str`][into_boxed_str].
844 /// [into_boxed_str]: https://doc.rust-lang.org/std/string/struct.String.html#method.into_boxed_str
849 /// use bumpalo::{Bump, collections::String};
851 /// let b = Bump::new();
853 /// let s = String::from_str_in("foo", &b);
855 /// assert_eq!(s.into_bump_str(), "foo");
857 pub fn into_bump_str(self) -> &'bump
str {
859 let s
= self.as_str();
866 /// Extracts a string slice containing the entire `String`.
873 /// use bumpalo::{Bump, collections::String};
875 /// let b = Bump::new();
877 /// let s = String::from_str_in("foo", &b);
879 /// assert_eq!("foo", s.as_str());
882 pub fn as_str(&self) -> &str {
886 /// Converts a `String` into a mutable string slice.
893 /// use bumpalo::{Bump, collections::String};
895 /// let b = Bump::new();
897 /// let mut s = String::from_str_in("foobar", &b);
898 /// let s_mut_str = s.as_mut_str();
900 /// s_mut_str.make_ascii_uppercase();
902 /// assert_eq!("FOOBAR", s_mut_str);
905 pub fn as_mut_str(&mut self) -> &mut str {
909 /// Appends a given string slice onto the end of this `String`.
916 /// use bumpalo::{Bump, collections::String};
918 /// let b = Bump::new();
920 /// let mut s = String::from_str_in("foo", &b);
922 /// s.push_str("bar");
924 /// assert_eq!("foobar", s);
927 pub fn push_str(&mut self, string
: &str) {
928 self.vec
.extend_from_slice(string
.as_bytes())
931 /// Returns this `String`'s capacity, in bytes.
938 /// use bumpalo::{Bump, collections::String};
940 /// let b = Bump::new();
942 /// let s = String::with_capacity_in(10, &b);
944 /// assert!(s.capacity() >= 10);
947 pub fn capacity(&self) -> usize {
951 /// Ensures that this `String`'s capacity is at least `additional` bytes
952 /// larger than its length.
954 /// The capacity may be increased by more than `additional` bytes if it
955 /// chooses, to prevent frequent reallocations.
957 /// If you do not want this "at least" behavior, see the [`reserve_exact`]
962 /// Panics if the new capacity overflows [`usize`].
964 /// [`reserve_exact`]: struct.String.html#method.reserve_exact
965 /// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
972 /// use bumpalo::{Bump, collections::String};
974 /// let b = Bump::new();
976 /// let mut s = String::new_in(&b);
980 /// assert!(s.capacity() >= 10);
983 /// This may not actually increase the capacity:
986 /// use bumpalo::{Bump, collections::String};
988 /// let b = Bump::new();
990 /// let mut s = String::with_capacity_in(10, &b);
994 /// // s now has a length of 2 and a capacity of 10
995 /// assert_eq!(2, s.len());
996 /// assert_eq!(10, s.capacity());
998 /// // Since we already have an extra 8 capacity, calling this...
1001 /// // ... doesn't actually increase.
1002 /// assert_eq!(10, s.capacity());
1005 pub fn reserve(&mut self, additional
: usize) {
1006 self.vec
.reserve(additional
)
1009 /// Ensures that this `String`'s capacity is `additional` bytes
1010 /// larger than its length.
1012 /// Consider using the [`reserve`] method unless you absolutely know
1013 /// better than the allocator.
1015 /// [`reserve`]: #method.reserve
1019 /// Panics if the new capacity overflows `usize`.
1026 /// use bumpalo::{Bump, collections::String};
1028 /// let b = Bump::new();
1030 /// let mut s = String::new_in(&b);
1032 /// s.reserve_exact(10);
1034 /// assert!(s.capacity() >= 10);
1037 /// This may not actually increase the capacity:
1040 /// use bumpalo::{Bump, collections::String};
1042 /// let b = Bump::new();
1044 /// let mut s = String::with_capacity_in(10, &b);
1048 /// // s now has a length of 2 and a capacity of 10
1049 /// assert_eq!(2, s.len());
1050 /// assert_eq!(10, s.capacity());
1052 /// // Since we already have an extra 8 capacity, calling this...
1053 /// s.reserve_exact(8);
1055 /// // ... doesn't actually increase.
1056 /// assert_eq!(10, s.capacity());
1059 pub fn reserve_exact(&mut self, additional
: usize) {
1060 self.vec
.reserve_exact(additional
)
1063 /// Shrinks the capacity of this `String` to match its length.
1070 /// use bumpalo::{Bump, collections::String};
1072 /// let b = Bump::new();
1074 /// let mut s = String::from_str_in("foo", &b);
1077 /// assert!(s.capacity() >= 100);
1079 /// s.shrink_to_fit();
1080 /// assert_eq!(3, s.capacity());
1083 pub fn shrink_to_fit(&mut self) {
1084 self.vec
.shrink_to_fit()
1087 /// Appends the given [`char`] to the end of this `String`.
1089 /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
1096 /// use bumpalo::{Bump, collections::String};
1098 /// let b = Bump::new();
1100 /// let mut s = String::from_str_in("abc", &b);
1106 /// assert_eq!("abc123", s);
1109 pub fn push(&mut self, ch
: char) {
1110 match ch
.len_utf8() {
1111 1 => self.vec
.push(ch
as u8),
1114 .extend_from_slice(ch
.encode_utf8(&mut [0; 4]).as_bytes()),
1118 /// Returns a byte slice of this `String`'s contents.
1120 /// The inverse of this method is [`from_utf8`].
1122 /// [`from_utf8`]: #method.from_utf8
1129 /// use bumpalo::{Bump, collections::String};
1131 /// let b = Bump::new();
1133 /// let s = String::from_str_in("hello", &b);
1135 /// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
1138 pub fn as_bytes(&self) -> &[u8] {
1142 /// Shortens this `String` to the specified length.
1144 /// If `new_len` is greater than the string's current length, this has no
1147 /// Note that this method has no effect on the allocated capacity
1152 /// Panics if `new_len` does not lie on a [`char`] boundary.
1154 /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
1161 /// use bumpalo::{Bump, collections::String};
1163 /// let b = Bump::new();
1165 /// let mut s = String::from_str_in("hello", &b);
1169 /// assert_eq!("he", s);
1172 pub fn truncate(&mut self, new_len
: usize) {
1173 if new_len
<= self.len() {
1174 assert
!(self.is_char_boundary(new_len
));
1175 self.vec
.truncate(new_len
)
1179 /// Removes the last character from the string buffer and returns it.
1181 /// Returns [`None`] if this `String` is empty.
1183 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
1190 /// use bumpalo::{Bump, collections::String};
1192 /// let b = Bump::new();
1194 /// let mut s = String::from_str_in("foo", &b);
1196 /// assert_eq!(s.pop(), Some('o'));
1197 /// assert_eq!(s.pop(), Some('o'));
1198 /// assert_eq!(s.pop(), Some('f'));
1200 /// assert_eq!(s.pop(), None);
1203 pub fn pop(&mut self) -> Option
<char> {
1204 let ch
= self.chars().rev().next()?
;
1205 let newlen
= self.len() - ch
.len_utf8();
1207 self.vec
.set_len(newlen
);
1212 /// Removes a [`char`] from this `String` at a byte position and returns it.
1214 /// This is an `O(n)` operation, as it requires copying every element in the
1219 /// Panics if `idx` is larger than or equal to the `String`'s length,
1220 /// or if it does not lie on a [`char`] boundary.
1222 /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
1229 /// use bumpalo::{Bump, collections::String};
1231 /// let b = Bump::new();
1233 /// let mut s = String::from_str_in("foo", &b);
1235 /// assert_eq!(s.remove(0), 'f');
1236 /// assert_eq!(s.remove(1), 'o');
1237 /// assert_eq!(s.remove(0), 'o');
1240 pub fn remove(&mut self, idx
: usize) -> char {
1241 let ch
= match self[idx
..].chars().next() {
1243 None
=> panic
!("cannot remove a char from the end of a string"),
1246 let next
= idx
+ ch
.len_utf8();
1247 let len
= self.len();
1250 self.vec
.as_ptr().add(next
),
1251 self.vec
.as_mut_ptr().add(idx
),
1254 self.vec
.set_len(len
- (next
- idx
));
1259 /// Retains only the characters specified by the predicate.
1261 /// In other words, remove all characters `c` such that `f(c)` returns `false`.
1262 /// This method operates in place and preserves the order of the retained
1268 /// use bumpalo::{Bump, collections::String};
1270 /// let b = Bump::new();
1272 /// let mut s = String::from_str_in("f_o_ob_ar", &b);
1274 /// s.retain(|c| c != '_');
1276 /// assert_eq!(s, "foobar");
1279 pub fn retain
<F
>(&mut self, mut f
: F
)
1281 F
: FnMut(char) -> bool
,
1283 let len
= self.len();
1284 let mut del_bytes
= 0;
1288 let ch
= unsafe { self.get_unchecked(idx..len).chars().next().unwrap() }
;
1289 let ch_len
= ch
.len_utf8();
1292 del_bytes
+= ch_len
;
1293 } else if del_bytes
> 0 {
1296 self.vec
.as_ptr().add(idx
),
1297 self.vec
.as_mut_ptr().add(idx
- del_bytes
),
1303 // Point idx to the next char
1309 self.vec
.set_len(len
- del_bytes
);
1314 /// Inserts a character into this `String` at a byte position.
1316 /// This is an `O(n)` operation as it requires copying every element in the
1321 /// Panics if `idx` is larger than the `String`'s length, or if it does not
1322 /// lie on a [`char`] boundary.
1324 /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
1331 /// use bumpalo::{Bump, collections::String};
1333 /// let b = Bump::new();
1335 /// let mut s = String::with_capacity_in(3, &b);
1337 /// s.insert(0, 'f');
1338 /// s.insert(1, 'o');
1339 /// s.insert(2, 'o');
1341 /// assert_eq!("foo", s);
1344 pub fn insert(&mut self, idx
: usize, ch
: char) {
1345 assert
!(self.is_char_boundary(idx
));
1346 let mut bits
= [0; 4];
1347 let bits
= ch
.encode_utf8(&mut bits
).as_bytes();
1350 self.insert_bytes(idx
, bits
);
1354 unsafe fn insert_bytes(&mut self, idx
: usize, bytes
: &[u8]) {
1355 let len
= self.len();
1356 let amt
= bytes
.len();
1357 self.vec
.reserve(amt
);
1360 self.vec
.as_ptr().add(idx
),
1361 self.vec
.as_mut_ptr().add(idx
+ amt
),
1364 ptr
::copy(bytes
.as_ptr(), self.vec
.as_mut_ptr().add(idx
), amt
);
1365 self.vec
.set_len(len
+ amt
);
1368 /// Inserts a string slice into this `String` at a byte position.
1370 /// This is an `O(n)` operation as it requires copying every element in the
1375 /// Panics if `idx` is larger than the `String`'s length, or if it does not
1376 /// lie on a [`char`] boundary.
1378 /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
1385 /// use bumpalo::{Bump, collections::String};
1387 /// let b = Bump::new();
1389 /// let mut s = String::from_str_in("bar", &b);
1391 /// s.insert_str(0, "foo");
1393 /// assert_eq!("foobar", s);
1396 pub fn insert_str(&mut self, idx
: usize, string
: &str) {
1397 assert
!(self.is_char_boundary(idx
));
1400 self.insert_bytes(idx
, string
.as_bytes());
1404 /// Returns a mutable reference to the contents of this `String`.
1408 /// This function is unsafe because the returned `&mut Vec` allows writing
1409 /// bytes which are not valid UTF-8. If this constraint is violated, using
1410 /// the original `String` after dropping the `&mut Vec` may violate memory
1411 /// safety, as it is assumed that `String`s are valid UTF-8.
1418 /// use bumpalo::{Bump, collections::String};
1420 /// let b = Bump::new();
1422 /// let mut s = String::from_str_in("hello", &b);
1425 /// let vec = s.as_mut_vec();
1426 /// assert_eq!(vec, &[104, 101, 108, 108, 111]);
1430 /// assert_eq!(s, "olleh");
1433 pub unsafe fn as_mut_vec(&mut self) -> &mut Vec
<'bump
, u8> {
1437 /// Returns the length of this `String`, in bytes.
1444 /// use bumpalo::{Bump, collections::String};
1446 /// let b = Bump::new();
1448 /// let a = String::from_str_in("foo", &b);
1450 /// assert_eq!(a.len(), 3);
1453 pub fn len(&self) -> usize {
1457 /// Returns `true` if this `String` has a length of zero.
1459 /// Returns `false` otherwise.
1466 /// use bumpalo::{Bump, collections::String};
1468 /// let b = Bump::new();
1470 /// let mut v = String::new_in(&b);
1471 /// assert!(v.is_empty());
1474 /// assert!(!v.is_empty());
1477 pub fn is_empty(&self) -> bool
{
1481 /// Splits the string into two at the given index.
1483 /// Returns a newly allocated `String`. `self` contains bytes `[0, at)`, and
1484 /// the returned `String` contains bytes `[at, len)`. `at` must be on the
1485 /// boundary of a UTF-8 code point.
1487 /// Note that the capacity of `self` does not change.
1491 /// Panics if `at` is not on a UTF-8 code point boundary, or if it is beyond the last
1492 /// code point of the string.
1497 /// use bumpalo::{Bump, collections::String};
1499 /// let b = Bump::new();
1501 /// let mut hello = String::from_str_in("Hello, World!", &b);
1502 /// let world = hello.split_off(7);
1503 /// assert_eq!(hello, "Hello, ");
1504 /// assert_eq!(world, "World!");
1507 pub fn split_off(&mut self, at
: usize) -> String
<'bump
> {
1508 assert
!(self.is_char_boundary(at
));
1509 let other
= self.vec
.split_off(at
);
1510 unsafe { String::from_utf8_unchecked(other) }
1513 /// Truncates this `String`, removing all contents.
1515 /// While this means the `String` will have a length of zero, it does not
1516 /// touch its capacity.
1523 /// use bumpalo::{Bump, collections::String};
1525 /// let b = Bump::new();
1527 /// let mut s = String::from_str_in("foo", &b);
1531 /// assert!(s.is_empty());
1532 /// assert_eq!(0, s.len());
1533 /// assert_eq!(3, s.capacity());
1536 pub fn clear(&mut self) {
1540 /// Creates a draining iterator that removes the specified range in the `String`
1541 /// and yields the removed `chars`.
1543 /// Note: The element range is removed even if the iterator is not
1544 /// consumed until the end.
1548 /// Panics if the starting point or end point do not lie on a [`char`]
1549 /// boundary, or if they're out of bounds.
1551 /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
1558 /// use bumpalo::{Bump, collections::String};
1560 /// let b = Bump::new();
1562 /// let mut s = String::from_str_in("α is alpha, β is beta", &b);
1563 /// let beta_offset = s.find('β').unwrap_or(s.len());
1565 /// // Remove the range up until the β from the string
1566 /// let t = String::from_iter_in(s.drain(..beta_offset), &b);
1567 /// assert_eq!(t, "α is alpha, ");
1568 /// assert_eq!(s, "β is beta");
1570 /// // A full range clears the string
1571 /// drop(s.drain(..));
1572 /// assert_eq!(s, "");
1574 pub fn drain
<'a
, R
>(&'a
mut self, range
: R
) -> Drain
<'a
, 'bump
>
1576 R
: RangeBounds
<usize>,
1580 // The String version of Drain does not have the memory safety issues
1581 // of the vector version. The data is just plain bytes.
1582 // Because the range removal happens in Drop, if the Drain iterator is leaked,
1583 // the removal will not happen.
1584 let len
= self.len();
1585 let start
= match range
.start_bound() {
1587 Excluded(&n
) => n
+ 1,
1590 let end
= match range
.end_bound() {
1591 Included(&n
) => n
+ 1,
1596 // Take out two simultaneous borrows. The &mut String won't be accessed
1597 // until iteration is over, in Drop.
1598 let self_ptr
= self as *mut _
;
1599 // slicing does the appropriate bounds checks
1600 let chars_iter
= self[start
..end
].chars();
1610 /// Removes the specified range in the string,
1611 /// and replaces it with the given string.
1612 /// The given string doesn't need to be the same length as the range.
1616 /// Panics if the starting point or end point do not lie on a [`char`]
1617 /// boundary, or if they're out of bounds.
1619 /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
1620 /// [`Vec::splice`]: ../vec/struct.Vec.html#method.splice
1627 /// use bumpalo::{Bump, collections::String};
1629 /// let b = Bump::new();
1631 /// let mut s = String::from_str_in("α is alpha, β is beta", &b);
1632 /// let beta_offset = s.find('β').unwrap_or(s.len());
1634 /// // Replace the range up until the β from the string
1635 /// s.replace_range(..beta_offset, "Α is capital alpha; ");
1636 /// assert_eq!(s, "Α is capital alpha; β is beta");
1638 pub fn replace_range
<R
>(&mut self, range
: R
, replace_with
: &str)
1640 R
: RangeBounds
<usize>,
1644 // Replace_range does not have the memory safety issues of a vector Splice.
1645 // of the vector version. The data is just plain bytes.
1647 match range
.start_bound() {
1648 Included(&n
) => assert
!(self.is_char_boundary(n
)),
1649 Excluded(&n
) => assert
!(self.is_char_boundary(n
+ 1)),
1652 match range
.end_bound() {
1653 Included(&n
) => assert
!(self.is_char_boundary(n
+ 1)),
1654 Excluded(&n
) => assert
!(self.is_char_boundary(n
)),
1658 unsafe { self.as_mut_vec() }
.splice(range
, replace_with
.bytes());
1662 impl<'bump
> FromUtf8Error
<'bump
> {
1663 /// Returns a slice of bytes that were attempted to convert to a `String`.
1670 /// use bumpalo::{Bump, collections::String};
1672 /// let b = Bump::new();
1674 /// // some invalid bytes, in a vector
1675 /// let bytes = bumpalo::vec![in &b; 0, 159];
1677 /// let value = String::from_utf8(bytes);
1679 /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
1681 pub fn as_bytes(&self) -> &[u8] {
1685 /// Returns the bytes that were attempted to convert to a `String`.
1687 /// This method is carefully constructed to avoid allocation. It will
1688 /// consume the error, moving out the bytes, so that a copy of the bytes
1689 /// does not need to be made.
1696 /// use bumpalo::{Bump, collections::String};
1698 /// let b = Bump::new();
1700 /// // some invalid bytes, in a vector
1701 /// let bytes = bumpalo::vec![in &b; 0, 159];
1703 /// let value = String::from_utf8(bytes);
1705 /// assert_eq!(bumpalo::vec![in &b; 0, 159], value.unwrap_err().into_bytes());
1707 pub fn into_bytes(self) -> Vec
<'bump
, u8> {
1711 /// Fetch a `Utf8Error` to get more details about the conversion failure.
1713 /// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
1714 /// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
1715 /// an analogue to `FromUtf8Error`. See its documentation for more details
1718 /// [`Utf8Error`]: https://doc.rust-lang.org/std/str/struct.Utf8Error.html
1719 /// [`std::str`]: https://doc.rust-lang.org/std/str/index.html
1720 /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
1721 /// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
1728 /// use bumpalo::{Bump, collections::String};
1730 /// let b = Bump::new();
1732 /// // some invalid bytes, in a vector
1733 /// let bytes = bumpalo::vec![in &b; 0, 159];
1735 /// let error = String::from_utf8(bytes).unwrap_err().utf8_error();
1737 /// // the first byte is invalid here
1738 /// assert_eq!(1, error.valid_up_to());
1740 pub fn utf8_error(&self) -> Utf8Error
{
1745 impl<'bump
> fmt
::Display
for FromUtf8Error
<'bump
> {
1746 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1747 fmt
::Display
::fmt(&self.error
, f
)
1751 impl fmt
::Display
for FromUtf16Error
{
1752 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1753 fmt
::Display
::fmt("invalid utf-16: lone surrogate found", f
)
1757 impl<'bump
> Clone
for String
<'bump
> {
1758 fn clone(&self) -> Self {
1760 vec
: self.vec
.clone(),
1764 fn clone_from(&mut self, source
: &Self) {
1765 self.vec
.clone_from(&source
.vec
);
1769 impl<'bump
> Extend
<char> for String
<'bump
> {
1770 fn extend
<I
: IntoIterator
<Item
= char>>(&mut self, iter
: I
) {
1771 let iterator
= iter
.into_iter();
1772 let (lower_bound
, _
) = iterator
.size_hint();
1773 self.reserve(lower_bound
);
1774 for ch
in iterator
{
1780 impl<'a
, 'bump
> Extend
<&'a
char> for String
<'bump
> {
1781 fn extend
<I
: IntoIterator
<Item
= &'a
char>>(&mut self, iter
: I
) {
1782 self.extend(iter
.into_iter().cloned());
1786 impl<'a
, 'bump
> Extend
<&'a
str> for String
<'bump
> {
1787 fn extend
<I
: IntoIterator
<Item
= &'a
str>>(&mut self, iter
: I
) {
1794 impl<'bump
> Extend
<String
<'bump
>> for String
<'bump
> {
1795 fn extend
<I
: IntoIterator
<Item
= String
<'bump
>>>(&mut self, iter
: I
) {
1802 impl<'bump
> Extend
<core_alloc
::string
::String
> for String
<'bump
> {
1803 fn extend
<I
: IntoIterator
<Item
= core_alloc
::string
::String
>>(&mut self, iter
: I
) {
1810 impl<'a
, 'bump
> Extend
<Cow
<'a
, str>> for String
<'bump
> {
1811 fn extend
<I
: IntoIterator
<Item
= Cow
<'a
, str>>>(&mut self, iter
: I
) {
1818 impl<'bump
> PartialEq
for String
<'bump
> {
1820 fn eq(&self, other
: &String
) -> bool
{
1821 PartialEq
::eq(&self[..], &other
[..])
1825 macro_rules
! impl_eq
{
1826 ($lhs
:ty
, $rhs
: ty
) => {
1827 impl<'a
, 'bump
> PartialEq
<$rhs
> for $lhs
{
1829 fn eq(&self, other
: &$rhs
) -> bool
{
1830 PartialEq
::eq(&self[..], &other
[..])
1834 impl<'a
, 'b
, 'bump
> PartialEq
<$lhs
> for $rhs
{
1836 fn eq(&self, other
: &$lhs
) -> bool
{
1837 PartialEq
::eq(&self[..], &other
[..])
1843 impl_eq
! { String<'bump>, str }
1844 impl_eq
! { String<'bump>, &'a str }
1845 impl_eq
! { Cow<'a, str>, String<'bump> }
1846 impl_eq
! { core_alloc::string::String, String<'bump> }
1848 impl<'bump
> fmt
::Display
for String
<'bump
> {
1850 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1851 fmt
::Display
::fmt(&**self, f
)
1855 impl<'bump
> fmt
::Debug
for String
<'bump
> {
1857 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1858 fmt
::Debug
::fmt(&**self, f
)
1862 impl<'bump
> hash
::Hash
for String
<'bump
> {
1864 fn hash
<H
: hash
::Hasher
>(&self, hasher
: &mut H
) {
1865 (**self).hash(hasher
)
1869 /// Implements the `+` operator for concatenating two strings.
1871 /// This consumes the `String<'bump>` on the left-hand side and re-uses its buffer (growing it if
1872 /// necessary). This is done to avoid allocating a new `String<'bump>` and copying the entire contents on
1873 /// every operation, which would lead to `O(n^2)` running time when building an `n`-byte string by
1874 /// repeated concatenation.
1876 /// The string on the right-hand side is only borrowed; its contents are copied into the returned
1877 /// `String<'bump>`.
1881 /// Concatenating two `String<'bump>`s takes the first by value and borrows the second:
1884 /// use bumpalo::{Bump, collections::String};
1886 /// let bump = Bump::new();
1888 /// let a = String::from_str_in("hello", &bump);
1889 /// let b = String::from_str_in(" world", &bump);
1891 /// // `a` is moved and can no longer be used here.
1894 /// If you want to keep using the first `String`, you can clone it and append to the clone instead:
1897 /// use bumpalo::{Bump, collections::String};
1899 /// let bump = Bump::new();
1901 /// let a = String::from_str_in("hello", &bump);
1902 /// let b = String::from_str_in(" world", &bump);
1903 /// let c = a.clone() + &b;
1904 /// // `a` is still valid here.
1907 /// Concatenating `&str` slices can be done by converting the first to a `String`:
1910 /// use bumpalo::{Bump, collections::String};
1912 /// let bump = Bump::new();
1914 /// let a = "hello";
1915 /// let b = " world";
1916 /// let c = String::from_str_in(a, &bump) + b;
1918 impl<'a
, 'bump
> Add
<&'a
str> for String
<'bump
> {
1919 type Output
= String
<'bump
>;
1922 fn add(mut self, other
: &str) -> String
<'bump
> {
1923 self.push_str(other
);
1928 /// Implements the `+=` operator for appending to a `String<'bump>`.
1930 /// This has the same behavior as the [`push_str`][String::push_str] method.
1931 impl<'a
, 'bump
> AddAssign
<&'a
str> for String
<'bump
> {
1933 fn add_assign(&mut self, other
: &str) {
1934 self.push_str(other
);
1938 impl<'bump
> ops
::Index
<ops
::Range
<usize>> for String
<'bump
> {
1942 fn index(&self, index
: ops
::Range
<usize>) -> &str {
1946 impl<'bump
> ops
::Index
<ops
::RangeTo
<usize>> for String
<'bump
> {
1950 fn index(&self, index
: ops
::RangeTo
<usize>) -> &str {
1954 impl<'bump
> ops
::Index
<ops
::RangeFrom
<usize>> for String
<'bump
> {
1958 fn index(&self, index
: ops
::RangeFrom
<usize>) -> &str {
1962 impl<'bump
> ops
::Index
<ops
::RangeFull
> for String
<'bump
> {
1966 fn index(&self, _index
: ops
::RangeFull
) -> &str {
1967 unsafe { str::from_utf8_unchecked(&self.vec) }
1970 impl<'bump
> ops
::Index
<ops
::RangeInclusive
<usize>> for String
<'bump
> {
1974 fn index(&self, index
: ops
::RangeInclusive
<usize>) -> &str {
1975 Index
::index(&**self, index
)
1978 impl<'bump
> ops
::Index
<ops
::RangeToInclusive
<usize>> for String
<'bump
> {
1982 fn index(&self, index
: ops
::RangeToInclusive
<usize>) -> &str {
1983 Index
::index(&**self, index
)
1987 impl<'bump
> ops
::IndexMut
<ops
::Range
<usize>> for String
<'bump
> {
1989 fn index_mut(&mut self, index
: ops
::Range
<usize>) -> &mut str {
1990 &mut self[..][index
]
1993 impl<'bump
> ops
::IndexMut
<ops
::RangeTo
<usize>> for String
<'bump
> {
1995 fn index_mut(&mut self, index
: ops
::RangeTo
<usize>) -> &mut str {
1996 &mut self[..][index
]
1999 impl<'bump
> ops
::IndexMut
<ops
::RangeFrom
<usize>> for String
<'bump
> {
2001 fn index_mut(&mut self, index
: ops
::RangeFrom
<usize>) -> &mut str {
2002 &mut self[..][index
]
2005 impl<'bump
> ops
::IndexMut
<ops
::RangeFull
> for String
<'bump
> {
2007 fn index_mut(&mut self, _index
: ops
::RangeFull
) -> &mut str {
2008 unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
2011 impl<'bump
> ops
::IndexMut
<ops
::RangeInclusive
<usize>> for String
<'bump
> {
2013 fn index_mut(&mut self, index
: ops
::RangeInclusive
<usize>) -> &mut str {
2014 IndexMut
::index_mut(&mut **self, index
)
2017 impl<'bump
> ops
::IndexMut
<ops
::RangeToInclusive
<usize>> for String
<'bump
> {
2019 fn index_mut(&mut self, index
: ops
::RangeToInclusive
<usize>) -> &mut str {
2020 IndexMut
::index_mut(&mut **self, index
)
2024 impl<'bump
> ops
::Deref
for String
<'bump
> {
2028 fn deref(&self) -> &str {
2029 unsafe { str::from_utf8_unchecked(&self.vec) }
2033 impl<'bump
> ops
::DerefMut
for String
<'bump
> {
2035 fn deref_mut(&mut self) -> &mut str {
2036 unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
2040 impl<'bump
> AsRef
<str> for String
<'bump
> {
2042 fn as_ref(&self) -> &str {
2047 impl<'bump
> AsRef
<[u8]> for String
<'bump
> {
2049 fn as_ref(&self) -> &[u8] {
2054 impl<'bump
> fmt
::Write
for String
<'bump
> {
2056 fn write_str(&mut self, s
: &str) -> fmt
::Result
{
2062 fn write_char(&mut self, c
: char) -> fmt
::Result
{
2068 impl<'bump
> Borrow
<str> for String
<'bump
> {
2070 fn borrow(&self) -> &str {
2075 impl<'bump
> BorrowMut
<str> for String
<'bump
> {
2077 fn borrow_mut(&mut self) -> &mut str {
2082 /// A draining iterator for `String`.
2084 /// This struct is created by the [`String::drain`] method. See its
2085 /// documentation for more information.
2086 pub struct Drain
<'a
, 'bump
> {
2087 /// Will be used as &'a mut String in the destructor
2088 string
: *mut String
<'bump
>,
2089 /// Start of part to remove
2091 /// End of part to remove
2093 /// Current remaining range to remove
2097 impl<'a
, 'bump
> fmt
::Debug
for Drain
<'a
, 'bump
> {
2098 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
2099 f
.pad("Drain { .. }")
2103 unsafe impl<'a
, 'bump
> Sync
for Drain
<'a
, 'bump
> {}
2104 unsafe impl<'a
, 'bump
> Send
for Drain
<'a
, 'bump
> {}
2106 impl<'a
, 'bump
> Drop
for Drain
<'a
, 'bump
> {
2107 fn drop(&mut self) {
2109 // Use Vec::drain. "Reaffirm" the bounds checks to avoid
2110 // panic code being inserted again.
2111 let self_vec
= (*self.string
).as_mut_vec();
2112 if self.start
<= self.end
&& self.end
<= self_vec
.len() {
2113 self_vec
.drain(self.start
..self.end
);
2119 // TODO: implement `AsRef<str/[u8]>` and `as_str`
2121 impl<'a
, 'bump
> Iterator
for Drain
<'a
, 'bump
> {
2125 fn next(&mut self) -> Option
<char> {
2129 fn size_hint(&self) -> (usize, Option
<usize>) {
2130 self.iter
.size_hint()
2134 impl<'a
, 'bump
> DoubleEndedIterator
for Drain
<'a
, 'bump
> {
2136 fn next_back(&mut self) -> Option
<char> {
2137 self.iter
.next_back()
2141 impl<'a
, 'bump
> FusedIterator
for Drain
<'a
, 'bump
> {}