Skip to main content

bump_scope/
mut_bump_string.rs

1use core::{
2    borrow::{Borrow, BorrowMut},
3    ffi::CStr,
4    fmt::{self, Debug, Display},
5    hash::Hash,
6    ops::{Deref, DerefMut, Index, IndexMut, Range, RangeBounds},
7    ptr::{self, NonNull},
8    slice::SliceIndex,
9    str,
10};
11
12use crate::{
13    BumpBox, ErrorBehavior, FromUtf8Error, FromUtf16Error, MutBumpVec,
14    alloc::AllocError,
15    fixed_bump_string::RawFixedBumpString,
16    owned_str,
17    polyfill::{self, transmute_mut, transmute_value},
18    traits::{MutBumpAllocatorTyped, MutBumpAllocatorTypedScope},
19};
20
21#[cfg(feature = "panic-on-alloc")]
22use crate::{PanicsOnAlloc, panic_on_error};
23
24/// This is like [`format!`](alloc_crate::format) but allocates inside a *mutable* bump allocator, returning a [`MutBumpString`].
25///
26/// If you don't need to push to the string after creation you can also use [`Bump::alloc_fmt_mut`](crate::Bump::alloc_fmt_mut).
27///
28/// # Panics
29/// If used without `try`, panics on allocation failure or if a formatting trait implementation returns an error.
30///
31/// # Errors
32/// If used with `try`, errors on allocation failure or if a formatting trait implementation returns an error.
33///
34/// # Examples
35///
36/// ```
37/// # use bump_scope::{Bump, mut_bump_format};
38/// # let mut bump: Bump = Bump::new();
39/// #
40/// let greeting = "Hello";
41/// let mut string = mut_bump_format!(in &mut bump, "{greeting}, world!");
42/// string.push_str(" How are you?");
43///
44/// assert_eq!(string, "Hello, world! How are you?");
45/// ```
46#[macro_export]
47macro_rules! mut_bump_format {
48    (in $bump:expr) => {{
49        $crate::MutBumpString::new_in($bump)
50    }};
51    (in $bump:expr, $($arg:tt)*) => {{
52        $crate::__mut_bump_format_panic_on_alloc!(in $bump, $($arg)*)
53    }};
54    (try in $bump:expr) => {{
55        Ok::<_, $crate::alloc::AllocError>($crate::MutBumpString::new_in($bump))
56    }};
57    (try in $bump:expr, $($arg:tt)*) => {{
58        let mut string = $crate::MutBumpString::new_in($bump);
59        match $crate::private::core::fmt::Write::write_fmt(&mut string, $crate::private::core::format_args!($($arg)*)) {
60            $crate::private::core::result::Result::Ok(_) => $crate::private::core::result::Result::Ok(string),
61            $crate::private::core::result::Result::Err(_) => $crate::private::core::result::Result::Err($crate::alloc::AllocError),
62        }
63    }};
64}
65
66#[doc(hidden)]
67#[macro_export]
68#[cfg(feature = "panic-on-alloc")]
69macro_rules! __mut_bump_format_panic_on_alloc {
70    (in $bump:expr, $($arg:tt)*) => {{
71        let mut string = $crate::private::PanicsOnAlloc($crate::MutBumpString::new_in($bump));
72        match $crate::private::core::fmt::Write::write_fmt(&mut string, $crate::private::core::format_args!($($arg)*)) {
73            $crate::private::core::result::Result::Ok(_) => string.0,
74            $crate::private::core::result::Result::Err(_) => $crate::private::format_trait_error(),
75        }
76    }};
77}
78
79#[doc(hidden)]
80#[macro_export]
81#[cfg(not(feature = "panic-on-alloc"))]
82macro_rules! __mut_bump_format_panic_on_alloc {
83    (in $bump:expr, $($arg:tt)*) => {{
84        compile_error!(concat!(
85            "the potentially panicking api of `mut_bump_format!` is not available\n",
86            "help: enable `bump-scope`'s \"panic-on-alloc\" feature or use `try`:\n",
87            "      `mut_bump_format!(try in ",
88            stringify!($bump),
89            ", ",
90            stringify!($($arg)*),
91            ")`"
92        ))
93    }};
94}
95
96/// A type like [`BumpString`](crate::BumpString), optimized for a mutable bump allocator.
97///
98/// It has the advantage that it can assume the entire remaining chunk space as its capacity.
99/// It also only needs to update the bump pointer when calling [`into_str`](Self::into_str) or [`into_boxed_str`](Self::into_boxed_str).
100///
101/// When you are done building the string, you can turn it into a `&str` with [`into_str`].
102///
103/// # Examples
104///
105/// You can create a `MutBumpString` from [a literal string][`&str`] with [`MutBumpString::from_str_in`]:
106///
107/// [`into_str`]: Self::into_str
108///
109/// ```
110/// # use bump_scope::{Bump, MutBumpString};
111/// # let mut bump: Bump = Bump::new();
112/// let hello = MutBumpString::from_str_in("Hello, world!", &mut bump);
113/// # let _ = hello;
114/// ```
115///
116/// You can append a [`char`] to a string with the [`push`] method, and
117/// append a [`&str`] with the [`push_str`] method:
118///
119/// ```
120/// # use bump_scope::{Bump, MutBumpString};
121/// # let mut bump: Bump = Bump::new();
122/// let mut hello = MutBumpString::from_str_in("Hello, ", &mut bump);
123///
124/// hello.push('w');
125/// hello.push_str("orld!");
126///
127/// assert_eq!(hello.as_str(), "Hello, world!");
128/// ```
129///
130/// [`push`]: Self::push
131/// [`push_str`]: Self::push_str
132///
133/// If you have a vector of UTF-8 bytes, you can create a `MutBumpString` from it with
134/// the [`from_utf8`] method:
135///
136/// ```
137/// # use bump_scope::{Bump, MutBumpString, mut_bump_vec};
138/// # let mut bump: Bump = Bump::new();
139/// // some bytes, in a vector
140/// let sparkle_heart = mut_bump_vec![in &mut bump; 240, 159, 146, 150];
141///
142/// // We know these bytes are valid, so we'll use `unwrap()`.
143/// let sparkle_heart = MutBumpString::from_utf8(sparkle_heart).unwrap();
144///
145/// assert_eq!("💖", sparkle_heart);
146/// ```
147///
148/// [`&str`]: prim@str "&str"
149/// [`from_utf8`]: Self::from_utf8
150#[repr(C)]
151pub struct MutBumpString<A> {
152    fixed: RawFixedBumpString,
153    allocator: A,
154}
155
156impl<A> MutBumpString<A> {
157    /// Constructs a new empty `MutBumpString`.
158    ///
159    /// Given that the `MutBumpString` is empty, this will not allocate any initial
160    /// buffer. While that means that this initial operation is very
161    /// inexpensive, it may cause excessive allocation later when you add
162    /// data. If you have an idea of how much data the `MutBumpString` will hold,
163    /// consider the [`with_capacity_in`] method to prevent excessive
164    /// re-allocation.
165    ///
166    /// [`with_capacity_in`]: Self::with_capacity_in
167    ///
168    /// # Examples
169    /// ```
170    /// # use bump_scope::{Bump, MutBumpString};
171    /// # let mut bump: Bump = Bump::new();
172    /// let string = MutBumpString::<_>::new_in(&mut bump);
173    /// assert_eq!(string.len(), 0);
174    /// assert_eq!(string.capacity(), 0);
175    /// ```
176    #[inline]
177    pub fn new_in(allocator: A) -> Self {
178        Self {
179            fixed: RawFixedBumpString::EMPTY,
180            allocator,
181        }
182    }
183
184    /// Converts a vector of bytes to a `MutBumpString`.
185    ///
186    /// A string ([`MutBumpString`]) is made of bytes ([`u8`]), and a vector of bytes
187    /// ([`MutBumpVec<u8>`]) is made of bytes, so this function converts between the
188    /// two. Not all byte slices are valid `MutBumpString`s, however: `MutBumpString`
189    /// requires that it is valid UTF-8. `from_utf8()` checks to ensure that
190    /// the bytes are valid UTF-8, and then does the conversion.
191    ///
192    /// If you are sure that the byte slice is valid UTF-8, and you don't want
193    /// to incur the overhead of the validity check, there is an unsafe version
194    /// of this function, [`from_utf8_unchecked`], which has the same behavior
195    /// but skips the check.
196    ///
197    /// This method will take care to not copy the vector, for efficiency's
198    /// sake.
199    ///
200    /// If you need a [`&str`] instead of a `MutBumpString`, consider
201    /// [`str::from_utf8`].
202    ///
203    /// The inverse of this method is [`into_bytes`].
204    ///
205    /// # Errors
206    ///
207    /// Returns [`Err`] if the slice is not UTF-8 with a description as to why the
208    /// provided bytes are not UTF-8. The vector you moved in is also included.
209    ///
210    /// # Examples
211    ///
212    /// Basic usage:
213    /// ```
214    /// # use bump_scope::{Bump, mut_bump_vec, MutBumpString};
215    /// # let mut bump: Bump = Bump::new();
216    /// // some bytes, in a vector
217    /// let sparkle_heart = mut_bump_vec![in &mut bump; 240, 159, 146, 150];
218    ///
219    /// // We know these bytes are valid, so we'll use `unwrap()`.
220    /// let sparkle_heart = MutBumpString::from_utf8(sparkle_heart).unwrap();
221    ///
222    /// assert_eq!("💖", sparkle_heart);
223    /// ```
224    ///
225    /// Incorrect bytes:
226    /// ```
227    /// # use bump_scope::{Bump, mut_bump_vec, MutBumpString};
228    /// # let mut bump: Bump = Bump::new();
229    /// // some invalid bytes, in a vector
230    /// let sparkle_heart = mut_bump_vec![in &mut bump; 0, 159, 146, 150];
231    ///
232    /// assert!(MutBumpString::from_utf8(sparkle_heart).is_err());
233    /// ```
234    ///
235    /// [`from_utf8_unchecked`]: Self::from_utf8_unchecked
236    /// [`MutBumpVec<u8>`]: MutBumpVec
237    /// [`&str`]: prim@str "&str"
238    /// [`into_bytes`]: Self::into_bytes
239    pub fn from_utf8(vec: MutBumpVec<u8, A>) -> Result<Self, FromUtf8Error<MutBumpVec<u8, A>>> {
240        match str::from_utf8(vec.as_slice()) {
241            // SAFETY: `MutBumpVec<u8>` and `MutBumpString` have the same representation;
242            // only the invariant that the bytes are utf8 is different.
243            Ok(_) => Ok(unsafe { transmute_value(vec) }),
244            Err(error) => Err(FromUtf8Error::new(error, vec)),
245        }
246    }
247
248    /// Converts a vector of bytes to a `MutBumpString` without checking that the
249    /// string contains valid UTF-8.
250    ///
251    /// See the safe version, [`from_utf8`](Self::from_utf8), for more details.
252    ///
253    /// # Safety
254    ///
255    /// The bytes passed in must be valid UTF-8.
256    ///
257    /// # Examples
258    ///
259    /// ```
260    /// # use bump_scope::{Bump, mut_bump_vec, MutBumpString};
261    /// # let mut bump: Bump = Bump::new();
262    /// // some bytes, in a vector
263    /// let sparkle_heart = mut_bump_vec![in &mut bump; 240, 159, 146, 150];
264    ///
265    /// let sparkle_heart = unsafe {
266    ///     MutBumpString::from_utf8_unchecked(sparkle_heart)
267    /// };
268    ///
269    /// assert_eq!("💖", sparkle_heart);
270    /// ```
271    #[must_use]
272    pub unsafe fn from_utf8_unchecked(vec: MutBumpVec<u8, A>) -> Self {
273        unsafe {
274            debug_assert!(str::from_utf8(vec.as_slice()).is_ok());
275
276            // SAFETY: `MutBumpVec<u8>` and `MutBumpString` have the same representation;
277            // only the invariant that the bytes are utf8 is different.
278            transmute_value(vec)
279        }
280    }
281
282    /// Returns this string's capacity, in bytes.
283    #[must_use]
284    #[inline(always)]
285    pub const fn capacity(&self) -> usize {
286        self.fixed.capacity()
287    }
288
289    /// Returns the length of this string, in bytes, not [`char`]s or
290    /// graphemes. In other words, it might not be what a human considers the
291    /// length of the string.
292    ///
293    /// # Examples
294    /// ```
295    /// # use bump_scope::{Bump, MutBumpString};
296    /// # let mut bump: Bump = Bump::new();
297    /// let a = MutBumpString::from_str_in("foo", &mut bump);
298    /// assert_eq!(a.len(), 3);
299    ///
300    /// let fancy_f = MutBumpString::from_str_in("ƒoo", &mut bump);
301    /// assert_eq!(fancy_f.len(), 4);
302    /// assert_eq!(fancy_f.chars().count(), 3);
303    /// ```
304    #[must_use]
305    #[inline(always)]
306    pub const fn len(&self) -> usize {
307        self.fixed.len()
308    }
309
310    /// Returns `true` if this string has a length of zero, and `false` otherwise.
311    ///
312    /// # Examples
313    /// ```
314    /// # use bump_scope::{Bump, MutBumpString};
315    /// # let mut bump: Bump = Bump::new();
316    /// let mut v = MutBumpString::new_in(&mut bump);
317    /// assert!(v.is_empty());
318    ///
319    /// v.push('a');
320    /// assert!(!v.is_empty());
321    /// ```
322    #[must_use]
323    #[inline(always)]
324    pub const fn is_empty(&self) -> bool {
325        self.fixed.len() == 0
326    }
327
328    /// Converts a `MutBumpString` into a `MutBumpVec<u8>`.
329    ///
330    /// This consumes the `MutBumpString`, so we do not need to copy its contents.
331    ///
332    /// # Examples
333    ///
334    /// ```
335    /// # use bump_scope::{Bump, MutBumpString};
336    /// # let mut bump: Bump = Bump::new();
337    /// let mut s = MutBumpString::new_in(&mut bump);
338    /// s.push_str("hello");
339    /// let bytes = s.into_bytes();
340    ///
341    /// assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);
342    /// ```
343    #[inline(always)]
344    #[must_use = "`self` will be dropped if the result is not used"]
345    pub fn into_bytes(self) -> MutBumpVec<u8, A> {
346        // SAFETY: `MutBumpVec<u8>` and `MutBumpString` have the same representation;
347        // only the invariant that the bytes are utf8 is different.
348        unsafe { transmute_value(self) }
349    }
350
351    #[track_caller]
352    #[inline(always)]
353    pub(crate) fn assert_char_boundary(&self, index: usize) {
354        unsafe { self.fixed.cook_ref() }.assert_char_boundary(index);
355    }
356
357    /// Removes the last character from the string buffer and returns it.
358    ///
359    /// Returns [`None`] if this string is empty.
360    ///
361    /// # Examples
362    ///
363    /// ```
364    /// # use bump_scope::{Bump, MutBumpString};
365    /// # let mut bump: Bump = Bump::new();
366    /// let mut s = MutBumpString::from_str_in("abč", &mut bump);
367    ///
368    /// assert_eq!(s.pop(), Some('č'));
369    /// assert_eq!(s.pop(), Some('b'));
370    /// assert_eq!(s.pop(), Some('a'));
371    ///
372    /// assert_eq!(s.pop(), None);
373    /// ```
374    #[inline]
375    pub fn pop(&mut self) -> Option<char> {
376        unsafe { self.fixed.cook_mut() }.pop()
377    }
378
379    /// Truncates this string, removing all contents.
380    ///
381    /// While this means the string will have a length of zero, it does not
382    /// touch its capacity.
383    ///
384    /// # Examples
385    ///
386    /// ```
387    /// # use bump_scope::{Bump, MutBumpString};
388    /// # let mut bump: Bump = Bump::new();
389    /// #
390    /// let mut s = MutBumpString::from_str_in("foo", &mut bump);
391    ///
392    /// s.clear();
393    ///
394    /// assert!(s.is_empty());
395    /// assert_eq!(s.len(), 0);
396    /// assert!(s.capacity() >= 3);
397    /// ```
398    #[inline]
399    pub fn clear(&mut self) {
400        unsafe { self.fixed.cook_mut() }.clear();
401    }
402
403    /// Shortens this string to the specified length.
404    ///
405    /// If `new_len` is greater than or equal to the string's current length, this has no
406    /// effect.
407    ///
408    /// Note that this method has no effect on the allocated capacity
409    /// of the string
410    ///
411    /// # Panics
412    ///
413    /// Panics if `new_len` does not lie on a [`char`] boundary.
414    ///
415    /// # Examples
416    ///
417    /// ```
418    /// # use bump_scope::{Bump, MutBumpString};
419    /// # let mut bump: Bump = Bump::new();
420    /// let mut s = MutBumpString::from_str_in("hello", &mut bump);
421    ///
422    /// s.truncate(2);
423    ///
424    /// assert_eq!(s, "he");
425    /// ```
426    #[inline]
427    pub fn truncate(&mut self, new_len: usize) {
428        unsafe { self.fixed.cook_mut() }.truncate(new_len);
429    }
430
431    /// Removes a [`char`] from this string at a byte position and returns it.
432    ///
433    /// This is an *O*(*n*) operation, as it requires copying every element in the
434    /// buffer.
435    ///
436    /// # Panics
437    ///
438    /// Panics if `idx` is larger than or equal to the string's length,
439    /// or if it does not lie on a [`char`] boundary.
440    ///
441    /// # Examples
442    ///
443    /// ```
444    /// # use bump_scope::{Bump, MutBumpString};
445    /// # let mut bump: Bump = Bump::new();
446    /// #
447    /// let mut s = MutBumpString::from_str_in("abç", &mut bump);
448    ///
449    /// assert_eq!(s.remove(0), 'a');
450    /// assert_eq!(s.remove(1), 'ç');
451    /// assert_eq!(s.remove(0), 'b');
452    /// ```
453    #[inline]
454    pub fn remove(&mut self, idx: usize) -> char {
455        unsafe { self.fixed.cook_mut() }.remove(idx)
456    }
457
458    /// Retains only the characters specified by the predicate.
459    ///
460    /// In other words, remove all characters `c` such that `f(c)` returns `false`.
461    /// This method operates in place, visiting each character exactly once in the
462    /// original order, and preserves the order of the retained characters.
463    ///
464    /// # Examples
465    ///
466    /// ```
467    /// # use bump_scope::{Bump, MutBumpString};
468    /// # let mut bump: Bump = Bump::new();
469    /// let mut s = MutBumpString::from_str_in("f_o_ob_ar", &mut bump);
470    ///
471    /// s.retain(|c| c != '_');
472    ///
473    /// assert_eq!(s, "foobar");
474    /// ```
475    ///
476    /// Because the elements are visited exactly once in the original order,
477    /// external state may be used to decide which elements to keep.
478    ///
479    /// ```
480    /// # use bump_scope::{Bump, MutBumpString};
481    /// # let mut bump: Bump = Bump::new();
482    /// let mut s = MutBumpString::from_str_in("abcde", &mut bump);
483    /// let keep = [false, true, true, false, true];
484    /// let mut iter = keep.iter();
485    /// s.retain(|_| *iter.next().unwrap());
486    /// assert_eq!(s, "bce");
487    /// ```
488    #[inline]
489    pub fn retain<F>(&mut self, f: F)
490    where
491        F: FnMut(char) -> bool,
492    {
493        unsafe { self.fixed.cook_mut() }.retain(f);
494    }
495
496    /// Removes the specified range from the string in bulk, returning all
497    /// removed characters as an iterator.
498    ///
499    /// The returned iterator keeps a mutable borrow on the string to optimize
500    /// its implementation.
501    ///
502    /// # Panics
503    ///
504    /// Panics if the starting point or end point do not lie on a [`char`]
505    /// boundary, or if they're out of bounds.
506    ///
507    /// # Leaking
508    ///
509    /// If the returned iterator goes out of scope without being dropped (due to
510    /// [`core::mem::forget`], for example), the string may still contain a copy
511    /// of any drained characters, or may have lost characters arbitrarily,
512    /// including characters outside the range.
513    ///
514    /// # Examples
515    ///
516    /// Basic usage:
517    ///
518    /// ```
519    /// # use bump_scope::{Bump, MutBumpString};
520    /// # let mut bump: Bump = Bump::new();
521    /// let mut s = MutBumpString::from_str_in("α is alpha, β is beta", &mut bump);
522    /// let beta_offset = s.find('β').unwrap_or(s.len());
523    ///
524    /// // Remove the range up until the β from the string
525    /// let t: String = s.drain(..beta_offset).collect();
526    /// assert_eq!(t, "α is alpha, ");
527    /// assert_eq!(s, "β is beta");
528    ///
529    /// // A full range clears the string, like `clear()` does
530    /// s.drain(..);
531    /// assert_eq!(s, "");
532    /// ```
533    pub fn drain<R>(&mut self, range: R) -> owned_str::Drain<'_>
534    where
535        R: RangeBounds<usize>,
536    {
537        unsafe { self.fixed.cook_mut() }.drain(range)
538    }
539
540    /// Extracts a string slice containing the entire `MutBumpString`.
541    #[must_use]
542    #[inline(always)]
543    pub fn as_str(&self) -> &str {
544        unsafe { self.fixed.cook_ref() }.as_str()
545    }
546
547    /// Converts a `MutBumpString` into a mutable string slice.
548    #[must_use]
549    #[inline(always)]
550    pub fn as_mut_str(&mut self) -> &mut str {
551        unsafe { self.fixed.cook_mut() }.as_mut_str()
552    }
553
554    /// Returns a byte slice of this `MutBumpString`'s contents.
555    #[must_use]
556    #[inline(always)]
557    pub fn as_bytes(&self) -> &[u8] {
558        unsafe { self.fixed.cook_ref() }.as_bytes()
559    }
560
561    /// Returns a mutable reference to the contents of this `MutBumpString`.
562    ///
563    /// # Safety
564    ///
565    /// This function is unsafe because the returned `&mut MutBumpVec<u8>` allows writing
566    /// bytes which are not valid UTF-8. If this constraint is violated, using
567    /// the original `MutBumpString` after dropping the `&mut MutBumpVec<u8>` may violate memory
568    /// safety, as `MutBumpString`s must be valid UTF-8.
569    #[must_use]
570    #[inline(always)]
571    pub unsafe fn as_mut_vec(&mut self) -> &mut MutBumpVec<u8, A> {
572        // SAFETY: `MutBumpVec<u8>` and `MutBumpString` have the same representation;
573        // only the invariant that the bytes are utf8 is different.
574        unsafe { transmute_mut(self) }
575    }
576
577    /// Returns a raw pointer to the slice, or a dangling raw pointer
578    /// valid for zero sized reads.
579    #[inline]
580    #[must_use]
581    pub fn as_ptr(&self) -> *const u8 {
582        self.fixed.as_ptr()
583    }
584
585    /// Returns an unsafe mutable pointer to slice, or a dangling
586    /// raw pointer valid for zero sized reads.
587    #[inline]
588    pub fn as_mut_ptr(&mut self) -> *mut u8 {
589        self.fixed.as_mut_ptr()
590    }
591
592    /// Returns a `NonNull` pointer to the string's buffer, or a dangling
593    /// `NonNull` pointer valid for zero sized reads if the string didn't allocate.
594    ///
595    /// The caller must ensure that the string outlives the pointer this
596    /// function returns, or else it will end up dangling.
597    /// Modifying the string may cause its buffer to be reallocated,
598    /// which would also make any pointers to it invalid.
599    ///
600    /// This method guarantees that for the purpose of the aliasing model, this method
601    /// does not materialize a reference to the underlying slice, and thus the returned pointer
602    /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
603    /// and [`as_non_null`].
604    /// Note that calling other methods that materialize references to the slice,
605    /// or references to specific elements you are planning on accessing through this pointer,
606    /// may still invalidate this pointer.
607    /// See the second example below for how this guarantee can be used.
608    ///
609    /// # Examples
610    ///
611    /// ```
612    /// # use bump_scope::{Bump, MutBumpString};
613    /// # let mut bump: Bump = Bump::new();
614    /// // Allocate vector big enough for 4 elements.
615    /// let size = 4;
616    /// let mut x = MutBumpString::with_capacity_in(size, &mut bump);
617    /// let x_ptr = x.as_non_null();
618    ///
619    /// // Initialize elements via raw pointer writes, then set length.
620    /// unsafe {
621    ///     for i in 0..size {
622    ///         x_ptr.add(i).write(i as u8 + b'a');
623    ///     }
624    ///     x.as_mut_vec().set_len(size);
625    /// }
626    /// assert_eq!(&*x, "abcd");
627    /// ```
628    ///
629    /// Due to the aliasing guarantee, the following code is legal:
630    ///
631    /// ```
632    /// # use bump_scope::{Bump, mut_bump_format};
633    /// # let mut bump: Bump = Bump::new();
634    /// unsafe {
635    ///     let v = mut_bump_format!(in &mut bump, "a");
636    ///     let ptr1 = v.as_non_null();
637    ///     ptr1.write(b'b');
638    ///     let ptr2 = v.as_non_null();
639    ///     ptr2.write(b'c');
640    ///     // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
641    ///     ptr1.write(b'd');
642    /// }
643    /// ```
644    ///
645    /// [`as_mut_ptr`]: Self::as_mut_ptr
646    /// [`as_ptr`]: Self::as_ptr
647    /// [`as_non_null`]: Self::as_non_null
648    #[must_use]
649    #[inline(always)]
650    pub const fn as_non_null(&self) -> NonNull<u8> {
651        self.fixed.as_non_null()
652    }
653
654    #[inline(always)]
655    pub(crate) unsafe fn set_len(&mut self, new_len: usize) {
656        unsafe { self.fixed.set_len(new_len) };
657    }
658}
659
660impl<A: MutBumpAllocatorTyped> MutBumpString<A> {
661    /// Constructs a new empty `MutBumpString` with at least the specified capacity
662    /// in the provided bump allocator.
663    ///
664    /// The string will be able to hold at least `capacity` bytes without reallocating.
665    /// This method allocates for as much elements as the current chunk can hold.
666    /// If `capacity` is 0, the string will not allocate.
667    ///
668    /// # Panics
669    /// Panics if the allocation fails.
670    ///
671    /// # Examples
672    /// ```
673    /// # use bump_scope::{Bump, MutBumpString};
674    /// # let mut bump: Bump = Bump::new();
675    /// let mut s = MutBumpString::<_>::with_capacity_in(10, &mut bump);
676    ///
677    /// // The String contains no chars, even though it has capacity for more
678    /// assert_eq!(s.len(), 0);
679    ///
680    /// // These are all done without reallocating...
681    /// let cap = s.capacity();
682    /// for _ in 0..10 {
683    ///     s.push('a');
684    /// }
685    ///
686    /// assert_eq!(s.capacity(), cap);
687    ///
688    /// // ...but this may make the string reallocate
689    /// s.push('a');
690    /// ```
691    #[must_use]
692    #[inline(always)]
693    #[cfg(feature = "panic-on-alloc")]
694    pub fn with_capacity_in(capacity: usize, allocator: A) -> Self {
695        panic_on_error(Self::generic_with_capacity_in(capacity, allocator))
696    }
697
698    /// Constructs a new empty `MutBumpString` with at least the specified capacity
699    /// in the provided bump allocator.
700    ///
701    /// The string will be able to hold at least `capacity` bytes without reallocating.
702    /// This method allocates for as much elements as the current chunk can hold.
703    /// If `capacity` is 0, the string will not allocate.
704    ///
705    /// # Errors
706    /// Errors if the allocation fails.
707    ///
708    /// # Examples
709    /// ```
710    /// # use bump_scope::{Bump, MutBumpString};
711    /// # let mut bump: Bump = Bump::new();
712    /// let mut s = MutBumpString::<_>::try_with_capacity_in(10, &mut bump)?;
713    ///
714    /// // The String contains no chars, even though it has capacity for more
715    /// assert_eq!(s.len(), 0);
716    ///
717    /// // These are all done without reallocating...
718    /// let cap = s.capacity();
719    /// for _ in 0..10 {
720    ///     s.push('a');
721    /// }
722    ///
723    /// assert_eq!(s.capacity(), cap);
724    ///
725    /// // ...but this may make the string reallocate
726    /// s.push('a');
727    /// # Ok::<(), bump_scope::alloc::AllocError>(())
728    /// ```
729    #[inline(always)]
730    pub fn try_with_capacity_in(capacity: usize, allocator: A) -> Result<Self, AllocError> {
731        Self::generic_with_capacity_in(capacity, allocator)
732    }
733
734    #[inline]
735    pub(crate) fn generic_with_capacity_in<E: ErrorBehavior>(capacity: usize, allocator: A) -> Result<Self, E> {
736        let mut allocator = allocator;
737
738        if capacity == 0 {
739            return Ok(Self {
740                fixed: RawFixedBumpString::EMPTY,
741                allocator,
742            });
743        }
744
745        Ok(Self {
746            fixed: unsafe { RawFixedBumpString::prepare_allocation(&mut allocator, capacity)? },
747            allocator,
748        })
749    }
750
751    /// Constructs a new `MutBumpString` from a `&str`.
752    ///
753    /// # Panics
754    /// Panics if the allocation fails.
755    ///
756    /// # Examples
757    /// ```
758    /// # use bump_scope::{Bump, MutBumpString};
759    /// # let mut bump: Bump = Bump::new();
760    /// let string = MutBumpString::from_str_in("Hello!", &mut bump);
761    /// assert_eq!(string, "Hello!");
762    /// ```
763    #[must_use]
764    #[inline(always)]
765    #[cfg(feature = "panic-on-alloc")]
766    pub fn from_str_in(string: &str, allocator: A) -> Self {
767        panic_on_error(Self::generic_from_str_in(string, allocator))
768    }
769
770    /// Constructs a new `MutBumpString` from a `&str`.
771    ///
772    /// # Errors
773    /// Errors if the allocation fails.
774    ///
775    /// # Examples
776    /// ```
777    /// # use bump_scope::{Bump, MutBumpString};
778    /// # let mut bump: Bump = Bump::new();
779    /// let string = MutBumpString::try_from_str_in("Hello!", &mut bump)?;
780    /// assert_eq!(string, "Hello!");
781    /// # Ok::<(), bump_scope::alloc::AllocError>(())
782    /// ```
783    #[inline(always)]
784    pub fn try_from_str_in(string: &str, allocator: A) -> Result<Self, AllocError> {
785        Self::generic_from_str_in(string, allocator)
786    }
787
788    #[inline]
789    pub(crate) fn generic_from_str_in<E: ErrorBehavior>(string: &str, allocator: A) -> Result<Self, E> {
790        let mut this = Self::generic_with_capacity_in(string.len(), allocator)?;
791
792        unsafe {
793            ptr::copy_nonoverlapping(string.as_ptr(), this.fixed.as_mut_ptr(), string.len());
794            this.as_mut_vec().set_len(string.len());
795        }
796
797        Ok(this)
798    }
799
800    /// Converts a slice of bytes to a string, including invalid characters.
801    ///
802    /// Strings are made of bytes ([`u8`]), and a slice of bytes
803    /// ([`&[u8]`][byteslice]) is made of bytes, so this function converts
804    /// between the two. Not all byte slices are valid strings, however: strings
805    /// are required to be valid UTF-8. During this conversion,
806    /// `from_utf8_lossy()` will replace any invalid UTF-8 sequences with
807    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD], which looks like this: �
808    ///
809    /// [byteslice]: prim@slice
810    /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
811    ///
812    /// If you are sure that the byte slice is valid UTF-8, and you don't want
813    /// to incur the overhead of the conversion, there is an unsafe version
814    /// of this function, [`from_utf8_unchecked`], which has the same behavior
815    /// but skips the checks.
816    ///
817    /// [`from_utf8_unchecked`]: Self::from_utf8_unchecked
818    ///
819    /// # Panics
820    /// Panics if the allocation fails.
821    ///
822    /// # Examples
823    /// Basic usage:
824    ///
825    /// ```
826    /// # use bump_scope::{Bump, MutBumpString};
827    /// # let mut bump: Bump = Bump::new();
828    /// // some bytes, in a vector
829    /// let sparkle_heart = [240, 159, 146, 150];
830    ///
831    /// let sparkle_heart = MutBumpString::from_utf8_lossy_in(&sparkle_heart, &mut bump);
832    ///
833    /// assert_eq!("💖", sparkle_heart);
834    /// ```
835    ///
836    /// Incorrect bytes:
837    ///
838    /// ```
839    /// # use bump_scope::{Bump, MutBumpString};
840    /// # let mut bump: Bump = Bump::new();
841    /// // some invalid bytes
842    /// let input = b"Hello \xF0\x90\x80World";
843    /// let output = MutBumpString::from_utf8_lossy_in(input, &mut bump);
844    ///
845    /// assert_eq!("Hello �World", output);
846    /// ```
847    #[must_use]
848    #[inline(always)]
849    #[cfg(feature = "panic-on-alloc")]
850    pub fn from_utf8_lossy_in(v: &[u8], allocator: A) -> Self {
851        panic_on_error(Self::generic_from_utf8_lossy_in(v, allocator))
852    }
853
854    /// Converts a slice of bytes to a string, including invalid characters.
855    ///
856    /// Strings are made of bytes ([`u8`]), and a slice of bytes
857    /// ([`&[u8]`][byteslice]) is made of bytes, so this function converts
858    /// between the two. Not all byte slices are valid strings, however: strings
859    /// are required to be valid UTF-8. During this conversion,
860    /// `from_utf8_lossy()` will replace any invalid UTF-8 sequences with
861    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD], which looks like this: �
862    ///
863    /// [byteslice]: prim@slice
864    /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
865    ///
866    /// If you are sure that the byte slice is valid UTF-8, and you don't want
867    /// to incur the overhead of the conversion, there is an unsafe version
868    /// of this function, [`from_utf8_unchecked`], which has the same behavior
869    /// but skips the checks.
870    ///
871    /// [`from_utf8_unchecked`]: Self::from_utf8_unchecked
872    ///
873    /// # Errors
874    /// Errors if the allocation fails.
875    ///
876    /// # Examples
877    /// Basic usage:
878    ///
879    /// ```
880    /// # use bump_scope::{Bump, MutBumpString};
881    /// # let mut bump: Bump = Bump::new();
882    /// // some bytes, in a vector
883    /// let sparkle_heart = [240, 159, 146, 150];
884    ///
885    /// let sparkle_heart = MutBumpString::try_from_utf8_lossy_in(&sparkle_heart, &mut bump)?;
886    ///
887    /// assert_eq!("💖", sparkle_heart);
888    /// # Ok::<(), bump_scope::alloc::AllocError>(())
889    /// ```
890    ///
891    /// Incorrect bytes:
892    ///
893    /// ```
894    /// # use bump_scope::{Bump, MutBumpString};
895    /// # let mut bump: Bump = Bump::new();
896    /// // some invalid bytes
897    /// let input = b"Hello \xF0\x90\x80World";
898    /// let output = MutBumpString::try_from_utf8_lossy_in(input, &mut bump)?;
899    ///
900    /// assert_eq!("Hello �World", output);
901    /// # Ok::<(), bump_scope::alloc::AllocError>(())
902    /// ```
903    #[inline(always)]
904    pub fn try_from_utf8_lossy_in(v: &[u8], allocator: A) -> Result<Self, AllocError> {
905        Self::generic_from_utf8_lossy_in(v, allocator)
906    }
907
908    pub(crate) fn generic_from_utf8_lossy_in<E: ErrorBehavior>(v: &[u8], allocator: A) -> Result<Self, E> {
909        let mut iter = v.utf8_chunks();
910
911        let first_valid = if let Some(chunk) = iter.next() {
912            let valid = chunk.valid();
913            if chunk.invalid().is_empty() {
914                debug_assert_eq!(valid.len(), v.len());
915                return Self::generic_from_str_in(valid, allocator);
916            }
917            valid
918        } else {
919            return Ok(Self::new_in(allocator));
920        };
921
922        const REPLACEMENT: &str = "\u{FFFD}";
923
924        let mut res = Self::generic_with_capacity_in(v.len(), allocator)?;
925        res.generic_push_str(first_valid)?;
926        res.generic_push_str(REPLACEMENT)?;
927
928        for chunk in iter {
929            res.generic_push_str(chunk.valid())?;
930            if !chunk.invalid().is_empty() {
931                res.generic_push_str(REPLACEMENT)?;
932            }
933        }
934
935        Ok(res)
936    }
937
938    /// Decode a UTF-16–encoded vector `v` into a `MutBumpString`, returning [`Err`]
939    /// if `v` contains any invalid data.
940    ///
941    /// # Panics
942    /// Panics if the allocation fails.
943    ///
944    /// # Examples
945    /// ```
946    /// # use bump_scope::{Bump, MutBumpString};
947    /// # let mut bump1: Bump = Bump::new();
948    /// # let mut bump2: Bump = Bump::new();
949    /// // 𝄞music
950    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
951    ///           0x0073, 0x0069, 0x0063];
952    /// assert_eq!(MutBumpString::from_str_in("𝄞music", &mut bump1),
953    ///            MutBumpString::from_utf16_in(v, &mut bump2).unwrap());
954    ///
955    /// // 𝄞mu<invalid>ic
956    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
957    ///           0xD800, 0x0069, 0x0063];
958    /// assert!(MutBumpString::from_utf16_in(v, &mut bump2).is_err());
959    /// ```
960    #[inline(always)]
961    #[cfg(feature = "panic-on-alloc")]
962    #[expect(clippy::missing_errors_doc)]
963    pub fn from_utf16_in(v: &[u16], allocator: A) -> Result<Self, FromUtf16Error> {
964        panic_on_error(Self::generic_from_utf16_in(v, allocator))
965    }
966
967    /// Decode a UTF-16–encoded vector `v` into a `MutBumpString`, returning [`Err`]
968    /// if `v` contains any invalid data.
969    ///
970    /// # Errors
971    /// Errors if the allocation fails.
972    ///
973    /// # Examples
974    /// ```
975    /// # use bump_scope::{Bump, MutBumpString};
976    /// # let mut bump1: Bump = Bump::new();
977    /// # let mut bump2: Bump = Bump::new();
978    /// // 𝄞music
979    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
980    ///           0x0073, 0x0069, 0x0063];
981    /// assert_eq!(MutBumpString::try_from_str_in("𝄞music", &mut bump1)?,
982    ///            MutBumpString::try_from_utf16_in(v, &mut bump2)?.unwrap());
983    ///
984    /// // 𝄞mu<invalid>ic
985    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
986    ///           0xD800, 0x0069, 0x0063];
987    /// assert!(MutBumpString::try_from_utf16_in(v, &mut bump2)?.is_err());
988    /// # Ok::<(), bump_scope::alloc::AllocError>(())
989    /// ```
990    #[inline(always)]
991    pub fn try_from_utf16_in(v: &[u16], allocator: A) -> Result<Result<Self, FromUtf16Error>, AllocError> {
992        Self::generic_from_utf16_in(v, allocator)
993    }
994
995    pub(crate) fn generic_from_utf16_in<E: ErrorBehavior>(
996        v: &[u16],
997        allocator: A,
998    ) -> Result<Result<Self, FromUtf16Error>, E> {
999        // This isn't done via collect::<Result<_, _>>() for performance reasons.
1000        // STD-FIXME: the function can be simplified again when #48994 is closed.
1001        let mut ret = Self::generic_with_capacity_in(v.len(), allocator)?;
1002
1003        for c in char::decode_utf16(v.iter().copied()) {
1004            if let Ok(c) = c {
1005                ret.generic_push(c)?;
1006            } else {
1007                return Ok(Err(FromUtf16Error(())));
1008            }
1009        }
1010
1011        Ok(Ok(ret))
1012    }
1013
1014    /// Decode a UTF-16–encoded slice `v` into a `MutBumpString`, replacing
1015    /// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
1016    ///
1017    /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
1018    ///
1019    /// # Panics
1020    /// Panics if the allocation fails.
1021    ///
1022    /// # Examples
1023    /// ```
1024    /// # use bump_scope::{Bump, MutBumpString};
1025    /// # let mut bump1: Bump = Bump::new();
1026    /// # let mut bump2: Bump = Bump::new();
1027    /// // 𝄞mus<invalid>ic<invalid>
1028    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
1029    ///           0x0073, 0xDD1E, 0x0069, 0x0063,
1030    ///           0xD834];
1031    ///
1032    /// assert_eq!(MutBumpString::from_str_in("𝄞mus\u{FFFD}ic\u{FFFD}", &mut bump1),
1033    ///            MutBumpString::from_utf16_lossy_in(v, &mut bump2));
1034    /// ```
1035    #[must_use]
1036    #[inline(always)]
1037    #[cfg(feature = "panic-on-alloc")]
1038    pub fn from_utf16_lossy_in(v: &[u16], allocator: A) -> Self {
1039        panic_on_error(Self::generic_from_utf16_lossy_in(v, allocator))
1040    }
1041
1042    /// Decode a UTF-16–encoded slice `v` into a `MutBumpString`, replacing
1043    /// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
1044    ///
1045    /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
1046    ///
1047    /// # Errors
1048    /// Errors if the allocation fails.
1049    ///
1050    /// # Examples
1051    /// ```
1052    /// # use bump_scope::{Bump, MutBumpString};
1053    /// # let mut bump1: Bump = Bump::new();
1054    /// # let mut bump2: Bump = Bump::new();
1055    /// // 𝄞mus<invalid>ic<invalid>
1056    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
1057    ///           0x0073, 0xDD1E, 0x0069, 0x0063,
1058    ///           0xD834];
1059    ///
1060    /// assert_eq!(MutBumpString::try_from_str_in("𝄞mus\u{FFFD}ic\u{FFFD}", &mut bump1)?,
1061    ///            MutBumpString::try_from_utf16_lossy_in(v, &mut bump2)?);
1062    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1063    /// ```
1064    #[inline(always)]
1065    pub fn try_from_utf16_lossy_in(v: &[u16], allocator: A) -> Result<Self, AllocError> {
1066        Self::generic_from_utf16_lossy_in(v, allocator)
1067    }
1068
1069    pub(crate) fn generic_from_utf16_lossy_in<E: ErrorBehavior>(v: &[u16], allocator: A) -> Result<Self, E> {
1070        let iter = char::decode_utf16(v.iter().copied());
1071        let capacity = iter.size_hint().0;
1072        let mut string = Self::generic_with_capacity_in(capacity, allocator)?;
1073
1074        for r in iter {
1075            string.generic_push(r.unwrap_or(char::REPLACEMENT_CHARACTER))?;
1076        }
1077
1078        Ok(string)
1079    }
1080
1081    /// Appends the given [`char`] to the end of this string.
1082    ///
1083    /// # Panics
1084    /// Panics if the allocation fails.
1085    ///
1086    /// # Examples
1087    /// ```
1088    /// # use bump_scope::{Bump, MutBumpString};
1089    /// # let mut bump: Bump = Bump::new();
1090    /// let mut s = MutBumpString::from_str_in("abc", &mut bump);
1091    ///
1092    /// s.push('1');
1093    /// s.push('2');
1094    /// s.push('3');
1095    ///
1096    /// assert_eq!(s, "abc123");
1097    /// ```
1098    #[inline(always)]
1099    #[cfg(feature = "panic-on-alloc")]
1100    pub fn push(&mut self, ch: char) {
1101        panic_on_error(self.generic_push(ch));
1102    }
1103
1104    /// Appends the given [`char`] to the end of this string.
1105    ///
1106    /// # Errors
1107    /// Errors if the allocation fails.
1108    ///
1109    /// # Examples
1110    /// ```
1111    /// # use bump_scope::{Bump, MutBumpString};
1112    /// # let mut bump: Bump = Bump::new();
1113    /// let mut s = MutBumpString::try_from_str_in("abc", &mut bump)?;
1114    ///
1115    /// s.try_push('1')?;
1116    /// s.try_push('2')?;
1117    /// s.try_push('3')?;
1118    ///
1119    /// assert_eq!(s, "abc123");
1120    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1121    /// ```
1122    #[inline(always)]
1123    pub fn try_push(&mut self, ch: char) -> Result<(), AllocError> {
1124        self.generic_push(ch)
1125    }
1126
1127    #[inline]
1128    pub(crate) fn generic_push<E: ErrorBehavior>(&mut self, ch: char) -> Result<(), E> {
1129        let vec = unsafe { self.as_mut_vec() };
1130
1131        match ch.len_utf8() {
1132            1 => vec.generic_push(ch as u8),
1133            _ => vec.generic_extend_from_slice_copy(ch.encode_utf8(&mut [0; 4]).as_bytes()),
1134        }
1135    }
1136
1137    /// Appends a given string slice onto the end of this string.
1138    ///
1139    /// # Panics
1140    /// Panics if the allocation fails.
1141    ///
1142    /// # Examples
1143    /// ```
1144    /// # use bump_scope::{Bump, MutBumpString};
1145    /// # let mut bump: Bump = Bump::new();
1146    /// let mut s = MutBumpString::from_str_in("foo", &mut bump);
1147    ///
1148    /// s.push_str("bar");
1149    ///
1150    /// assert_eq!(s, "foobar");
1151    /// ```
1152    #[inline(always)]
1153    #[cfg(feature = "panic-on-alloc")]
1154    pub fn push_str(&mut self, string: &str) {
1155        panic_on_error(self.generic_push_str(string));
1156    }
1157
1158    /// Appends a given string slice onto the end of this string.
1159    ///
1160    /// # Errors
1161    /// Errors if the allocation fails.
1162    ///
1163    /// # Examples
1164    /// ```
1165    /// # use bump_scope::{Bump, MutBumpString};
1166    /// # let mut bump: Bump = Bump::new();
1167    /// let mut s = MutBumpString::try_from_str_in("foo", &mut bump)?;
1168    ///
1169    /// s.try_push_str("bar")?;
1170    ///
1171    /// assert_eq!(s, "foobar");
1172    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1173    /// ```
1174    #[inline(always)]
1175    pub fn try_push_str(&mut self, string: &str) -> Result<(), AllocError> {
1176        self.generic_push_str(string)
1177    }
1178
1179    #[inline]
1180    pub(crate) fn generic_push_str<E: ErrorBehavior>(&mut self, string: &str) -> Result<(), E> {
1181        let vec = unsafe { self.as_mut_vec() };
1182        vec.generic_extend_from_slice_copy(string.as_bytes())
1183    }
1184
1185    /// Inserts a character into this string at a byte position.
1186    ///
1187    /// This is an *O*(*n*) operation as it requires copying every element in the
1188    /// buffer.
1189    ///
1190    /// # Panics
1191    /// Panics if the allocation fails.
1192    ///
1193    /// Panics if `idx` is larger than the string's length, or if it does not
1194    /// lie on a [`char`] boundary.
1195    ///
1196    /// # Examples
1197    /// ```
1198    /// # use bump_scope::{Bump, MutBumpString};
1199    /// # let mut bump: Bump = Bump::new();
1200    /// let mut s = MutBumpString::with_capacity_in(3, &mut bump);
1201    ///
1202    /// s.insert(0, 'f');
1203    /// s.insert(1, 'o');
1204    /// s.insert(2, 'o');
1205    ///
1206    /// assert_eq!("foo", s);
1207    /// ```
1208    #[inline(always)]
1209    #[cfg(feature = "panic-on-alloc")]
1210    pub fn insert(&mut self, idx: usize, ch: char) {
1211        panic_on_error(self.generic_insert(idx, ch));
1212    }
1213
1214    /// Inserts a character into this string at a byte position.
1215    ///
1216    /// This is an *O*(*n*) operation as it requires copying every element in the
1217    /// buffer.
1218    ///
1219    /// # Panics
1220    /// Panics if `idx` is larger than the string's length, or if it does not
1221    /// lie on a [`char`] boundary.
1222    ///
1223    /// # Errors
1224    /// Errors if the allocation fails.
1225    ///
1226    /// # Examples
1227    /// ```
1228    /// # use bump_scope::{Bump, MutBumpString};
1229    /// # let mut bump: Bump = Bump::new();
1230    /// let mut s = MutBumpString::try_with_capacity_in(3, &mut bump)?;
1231    ///
1232    /// s.try_insert(0, 'f')?;
1233    /// s.try_insert(1, 'o')?;
1234    /// s.try_insert(2, 'o')?;
1235    ///
1236    /// assert_eq!("foo", s);
1237    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1238    /// ```
1239    #[inline(always)]
1240    pub fn try_insert(&mut self, idx: usize, ch: char) -> Result<(), AllocError> {
1241        self.generic_insert(idx, ch)
1242    }
1243
1244    #[inline]
1245    pub(crate) fn generic_insert<E: ErrorBehavior>(&mut self, idx: usize, ch: char) -> Result<(), E> {
1246        self.assert_char_boundary(idx);
1247
1248        let mut bits = [0; 4];
1249        let bits = ch.encode_utf8(&mut bits).as_bytes();
1250
1251        unsafe { self.insert_bytes(idx, bits) }
1252    }
1253
1254    /// Inserts a string slice into this string at a byte position.
1255    ///
1256    /// This is an *O*(*n*) operation as it requires copying every element in the
1257    /// buffer.
1258    ///
1259    /// # Panics
1260    /// Panics if the allocation fails.
1261    ///
1262    /// Panics if `idx` is larger than the string's length, or if it does not
1263    /// lie on a [`char`] boundary.
1264    ///
1265    /// # Examples
1266    /// ```
1267    /// # use bump_scope::{Bump, MutBumpString};
1268    /// # let mut bump: Bump = Bump::new();
1269    /// let mut s = MutBumpString::from_str_in("bar", &mut bump);
1270    ///
1271    /// s.insert_str(0, "foo");
1272    ///
1273    /// assert_eq!("foobar", s);
1274    /// ```
1275    #[inline(always)]
1276    #[cfg(feature = "panic-on-alloc")]
1277    pub fn insert_str(&mut self, idx: usize, string: &str) {
1278        panic_on_error(self.generic_insert_str(idx, string));
1279    }
1280
1281    /// Inserts a string slice into this string at a byte position.
1282    ///
1283    /// This is an *O*(*n*) operation as it requires copying every element in the
1284    /// buffer.
1285    ///
1286    /// # Panics
1287    /// Panics if `idx` is larger than the string's length, or if it does not
1288    /// lie on a [`char`] boundary.
1289    ///
1290    /// # Errors
1291    /// Errors if the allocation fails.
1292    ///
1293    /// # Examples
1294    /// ```
1295    /// # use bump_scope::{Bump, MutBumpString};
1296    /// # let mut bump: Bump = Bump::new();
1297    /// let mut s = MutBumpString::try_from_str_in("bar", &mut bump)?;
1298    ///
1299    /// s.try_insert_str(0, "foo")?;
1300    ///
1301    /// assert_eq!("foobar", s);
1302    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1303    /// ```
1304    #[inline(always)]
1305    pub fn try_insert_str(&mut self, idx: usize, string: &str) -> Result<(), AllocError> {
1306        self.generic_insert_str(idx, string)
1307    }
1308
1309    #[inline]
1310    pub(crate) fn generic_insert_str<E: ErrorBehavior>(&mut self, idx: usize, string: &str) -> Result<(), E> {
1311        self.assert_char_boundary(idx);
1312        unsafe { self.insert_bytes(idx, string.as_bytes()) }
1313    }
1314
1315    /// Copies elements from `src` range to the end of the string.
1316    ///
1317    /// # Panics
1318    /// Panics if the allocation fails.
1319    ///
1320    /// Panics if the starting point or end point do not lie on a [`char`]
1321    /// boundary, or if they're out of bounds.
1322    ///
1323    /// # Examples
1324    /// ```
1325    /// # use bump_scope::{Bump, MutBumpString};
1326    /// # let mut bump: Bump = Bump::new();
1327    /// let mut string = MutBumpString::from_str_in("abcde", &mut bump);
1328    ///
1329    /// string.extend_from_within(2..);
1330    /// assert_eq!(string, "abcdecde");
1331    ///
1332    /// string.extend_from_within(..2);
1333    /// assert_eq!(string, "abcdecdeab");
1334    ///
1335    /// string.extend_from_within(4..8);
1336    /// assert_eq!(string, "abcdecdeabecde");
1337    /// ```
1338    #[inline(always)]
1339    #[cfg(feature = "panic-on-alloc")]
1340    pub fn extend_from_within<R>(&mut self, src: R)
1341    where
1342        R: RangeBounds<usize>,
1343    {
1344        panic_on_error(self.generic_extend_from_within(src));
1345    }
1346
1347    /// Copies elements from `src` range to the end of the string.
1348    ///
1349    /// # Panics
1350    /// Panics if the starting point or end point do not lie on a [`char`]
1351    /// boundary, or if they're out of bounds.
1352    ///
1353    /// # Errors
1354    /// Errors if the allocation fails.
1355    ///
1356    /// # Examples
1357    /// ```
1358    /// # use bump_scope::{Bump, MutBumpString};
1359    /// # let mut bump: Bump = Bump::new();
1360    /// let mut string = MutBumpString::try_from_str_in("abcde", &mut bump)?;
1361    ///
1362    /// string.try_extend_from_within(2..)?;
1363    /// assert_eq!(string, "abcdecde");
1364    ///
1365    /// string.try_extend_from_within(..2)?;
1366    /// assert_eq!(string, "abcdecdeab");
1367    ///
1368    /// string.try_extend_from_within(4..8)?;
1369    /// assert_eq!(string, "abcdecdeabecde");
1370    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1371    /// ```
1372    #[inline(always)]
1373    pub fn try_extend_from_within<R>(&mut self, src: R) -> Result<(), AllocError>
1374    where
1375        R: RangeBounds<usize>,
1376    {
1377        self.generic_extend_from_within(src)
1378    }
1379
1380    #[inline]
1381    pub(crate) fn generic_extend_from_within<E: ErrorBehavior, R: RangeBounds<usize>>(&mut self, src: R) -> Result<(), E> {
1382        let src @ Range { start, end } = polyfill::slice::range(src, ..self.len());
1383
1384        self.assert_char_boundary(start);
1385        self.assert_char_boundary(end);
1386
1387        let vec = unsafe { self.as_mut_vec() };
1388        vec.generic_extend_from_within_copy(src)
1389    }
1390
1391    /// Extends this string by pushing `additional` new zero bytes.
1392    ///
1393    /// # Panics
1394    /// Panics if the allocation fails.
1395    ///
1396    /// # Examples
1397    /// ```
1398    /// # use bump_scope::{Bump, MutBumpString};
1399    /// # let mut bump: Bump = Bump::new();
1400    /// let mut string = MutBumpString::from_str_in("What?", &mut bump);
1401    /// string.extend_zeroed(3);
1402    /// assert_eq!(string, "What?\0\0\0");
1403    /// ```
1404    #[inline(always)]
1405    #[cfg(feature = "panic-on-alloc")]
1406    pub fn extend_zeroed(&mut self, additional: usize) {
1407        panic_on_error(self.generic_extend_zeroed(additional));
1408    }
1409
1410    /// Extends this string by pushing `additional` new zero bytes.
1411    ///
1412    /// # Errors
1413    /// Errors if the allocation fails.
1414    ///
1415    /// # Examples
1416    /// ```
1417    /// # use bump_scope::{Bump, MutBumpString};
1418    /// # let mut bump: Bump = Bump::new();
1419    /// let mut string = MutBumpString::try_from_str_in("What?", &mut bump)?;
1420    /// string.try_extend_zeroed(3)?;
1421    /// assert_eq!(string, "What?\0\0\0");
1422    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1423    /// ```
1424    #[inline(always)]
1425    pub fn try_extend_zeroed(&mut self, additional: usize) -> Result<(), AllocError> {
1426        self.generic_extend_zeroed(additional)
1427    }
1428
1429    #[inline]
1430    pub(crate) fn generic_extend_zeroed<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
1431        let vec = unsafe { self.as_mut_vec() };
1432
1433        vec.generic_reserve(additional)?;
1434
1435        unsafe {
1436            let ptr = vec.as_mut_ptr();
1437            let len = vec.len();
1438
1439            ptr.add(len).write_bytes(0, additional);
1440            vec.set_len(len + additional);
1441        }
1442
1443        Ok(())
1444    }
1445
1446    /// Removes the specified range in the string,
1447    /// and replaces it with the given string.
1448    /// The given string doesn't need to be the same length as the range.
1449    ///
1450    /// # Panics
1451    /// Panics if the allocation fails.
1452    ///
1453    /// Panics if the starting point or end point do not lie on a [`char`]
1454    /// boundary, or if they're out of bounds.
1455    ///
1456    /// # Examples
1457    /// ```
1458    /// # use bump_scope::{Bump, MutBumpString};
1459    /// # let mut bump: Bump = Bump::new();
1460    /// let mut s = MutBumpString::from_str_in("α is alpha, β is beta", &mut bump);
1461    /// let beta_offset = s.find('β').unwrap_or(s.len());
1462    ///
1463    /// // Replace the range up until the β from the string
1464    /// s.replace_range(..beta_offset, "Α is capital alpha; ");
1465    /// assert_eq!(s, "Α is capital alpha; β is beta");
1466    /// ```
1467    #[inline(always)]
1468    #[cfg(feature = "panic-on-alloc")]
1469    pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
1470    where
1471        R: RangeBounds<usize>,
1472    {
1473        panic_on_error(self.generic_replace_range(range, replace_with));
1474    }
1475
1476    /// Removes the specified range in the string,
1477    /// and replaces it with the given string.
1478    /// The given string doesn't need to be the same length as the range.
1479    ///
1480    /// # Panics
1481    /// Panics if the starting point or end point do not lie on a [`char`]
1482    /// boundary, or if they're out of bounds.
1483    ///
1484    /// # Errors
1485    /// Errors if the allocation fails.
1486    ///
1487    /// # Examples
1488    /// ```
1489    /// # use bump_scope::{Bump, MutBumpString};
1490    /// # let mut bump: Bump = Bump::new();
1491    /// let mut s = MutBumpString::try_from_str_in("α is alpha, β is beta", &mut bump)?;
1492    /// let beta_offset = s.find('β').unwrap_or(s.len());
1493    ///
1494    /// // Replace the range up until the β from the string
1495    /// s.try_replace_range(..beta_offset, "Α is capital alpha; ")?;
1496    /// assert_eq!(s, "Α is capital alpha; β is beta");
1497    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1498    /// ```
1499    #[inline(always)]
1500    pub fn try_replace_range<R>(&mut self, range: R, replace_with: &str) -> Result<(), AllocError>
1501    where
1502        R: RangeBounds<usize>,
1503    {
1504        self.generic_replace_range(range, replace_with)
1505    }
1506
1507    #[inline]
1508    pub(crate) fn generic_replace_range<E: ErrorBehavior, R: RangeBounds<usize>>(
1509        &mut self,
1510        range: R,
1511        replace_with: &str,
1512    ) -> Result<(), E> {
1513        let Range { start, end } = polyfill::slice::range(range, ..self.len());
1514
1515        self.assert_char_boundary(start);
1516        self.assert_char_boundary(end);
1517
1518        let range_len = end - start;
1519        let given_len = replace_with.len();
1520
1521        let additional_len = given_len.saturating_sub(range_len);
1522        self.generic_reserve(additional_len)?;
1523
1524        // move the tail
1525        if range_len != given_len {
1526            unsafe {
1527                let src = self.as_ptr().add(end);
1528                let dst = self.as_mut_ptr().add(start + given_len);
1529                let len = self.len() - end;
1530                src.copy_to(dst, len);
1531            }
1532        }
1533
1534        // fill with given string
1535        unsafe {
1536            let src = replace_with.as_ptr();
1537            let dst = self.as_mut_ptr().add(start);
1538            let len = replace_with.len();
1539            src.copy_to_nonoverlapping(dst, len);
1540        }
1541
1542        // update len
1543        #[expect(clippy::cast_sign_loss, clippy::cast_possible_wrap)]
1544        unsafe {
1545            // Casting to `isize` is fine because per `Layout`'s rules all the `*len`s must be
1546            // less than isize::MAX. Subtracting two positive `isize`s can't overflow.
1547            let len_diff = given_len as isize - range_len as isize;
1548            self.set_len((self.len() as isize + len_diff) as usize);
1549        }
1550
1551        Ok(())
1552    }
1553
1554    /// Reserves capacity for at least `additional` bytes more than the
1555    /// current length. The allocator may reserve more space to speculatively
1556    /// avoid frequent allocations. After calling `reserve`,
1557    /// capacity will be greater than or equal to `self.len() + additional`.
1558    /// Does nothing if capacity is already sufficient.
1559    ///
1560    /// # Panics
1561    /// Panics if the allocation fails.
1562    ///
1563    /// # Examples
1564    /// Basic usage:
1565    ///
1566    /// ```
1567    /// # use bump_scope::{Bump, MutBumpString};
1568    /// # let mut bump: Bump = Bump::new();
1569    /// let mut s = MutBumpString::new_in(&mut bump);
1570    ///
1571    /// s.reserve(10);
1572    ///
1573    /// assert!(s.capacity() >= 10);
1574    /// ```
1575    ///
1576    /// This might not actually increase the capacity:
1577    ///
1578    /// ```
1579    /// # use bump_scope::{Bump, MutBumpString};
1580    /// # let mut bump: Bump = Bump::new();
1581    /// let mut s = MutBumpString::with_capacity_in(10, &mut bump);
1582    /// s.push('a');
1583    /// s.push('b');
1584    ///
1585    /// // s now has a length of 2 and a capacity of at least 10
1586    /// let capacity = s.capacity();
1587    /// assert_eq!(2, s.len());
1588    /// assert!(capacity >= 10);
1589    ///
1590    /// // Since we already have at least an extra 8 capacity, calling this...
1591    /// s.reserve(8);
1592    ///
1593    /// // ... doesn't actually increase.
1594    /// assert_eq!(capacity, s.capacity());
1595    /// ```
1596    #[inline(always)]
1597    #[cfg(feature = "panic-on-alloc")]
1598    pub fn reserve(&mut self, additional: usize) {
1599        panic_on_error(self.generic_reserve(additional));
1600    }
1601
1602    /// Reserves capacity for at least `additional` bytes more than the
1603    /// current length. The allocator may reserve more space to speculatively
1604    /// avoid frequent allocations. After calling `reserve`,
1605    /// capacity will be greater than or equal to `self.len() + additional`.
1606    /// Does nothing if capacity is already sufficient.
1607    ///
1608    /// # Errors
1609    /// Errors if the allocation fails.
1610    ///
1611    /// # Examples
1612    /// Basic usage:
1613    ///
1614    /// ```
1615    /// # use bump_scope::{Bump, MutBumpString};
1616    /// # let mut bump: Bump = Bump::new();
1617    /// let mut s = MutBumpString::new_in(&mut bump);
1618    ///
1619    /// s.try_reserve(10)?;
1620    ///
1621    /// assert!(s.capacity() >= 10);
1622    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1623    /// ```
1624    ///
1625    /// This might not actually increase the capacity:
1626    ///
1627    /// ```
1628    /// # use bump_scope::{Bump, MutBumpString};
1629    /// # let mut bump: Bump = Bump::new();
1630    /// let mut s = MutBumpString::try_with_capacity_in(10, &mut bump)?;
1631    /// s.push('a');
1632    /// s.push('b');
1633    ///
1634    /// // s now has a length of 2 and a capacity of at least 10
1635    /// let capacity = s.capacity();
1636    /// assert_eq!(2, s.len());
1637    /// assert!(capacity >= 10);
1638    ///
1639    /// // Since we already have at least an extra 8 capacity, calling this...
1640    /// s.try_reserve(8)?;
1641    ///
1642    /// // ... doesn't actually increase.
1643    /// assert_eq!(capacity, s.capacity());
1644    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1645    /// ```
1646    #[inline(always)]
1647    pub fn try_reserve(&mut self, additional: usize) -> Result<(), AllocError> {
1648        self.generic_reserve(additional)
1649    }
1650
1651    #[inline]
1652    pub(crate) fn generic_reserve<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
1653        let vec = unsafe { self.as_mut_vec() };
1654        vec.generic_reserve(additional)
1655    }
1656
1657    /// Reserves the minimum capacity for at least `additional` bytes more than
1658    /// the current length. Unlike [`reserve`], this will not
1659    /// deliberately over-allocate to speculatively avoid frequent allocations.
1660    /// After calling `reserve_exact`, capacity will be greater than or equal to
1661    /// `self.len() + additional`. Does nothing if the capacity is already
1662    /// sufficient.
1663    ///
1664    /// [`reserve`]: Self::reserve
1665    ///
1666    /// # Panics
1667    /// Panics if the allocation fails.
1668    ///
1669    /// # Examples
1670    /// Basic usage:
1671    ///
1672    /// ```
1673    /// # use bump_scope::{Bump, MutBumpString};
1674    /// # let mut bump: Bump = Bump::new();
1675    /// let mut s = MutBumpString::new_in(&mut bump);
1676    ///
1677    /// s.reserve_exact(10);
1678    ///
1679    /// assert!(s.capacity() >= 10);
1680    /// ```
1681    ///
1682    /// This might not actually increase the capacity:
1683    ///
1684    /// ```
1685    /// # use bump_scope::{Bump, MutBumpString};
1686    /// # let mut bump: Bump = Bump::new();
1687    /// let mut s = MutBumpString::with_capacity_in(10, &mut bump);
1688    /// s.push('a');
1689    /// s.push('b');
1690    ///
1691    /// // s now has a length of 2 and a capacity of at least 10
1692    /// let capacity = s.capacity();
1693    /// assert_eq!(2, s.len());
1694    /// assert!(capacity >= 10);
1695    ///
1696    /// // Since we already have at least an extra 8 capacity, calling this...
1697    /// s.reserve_exact(8);
1698    ///
1699    /// // ... doesn't actually increase.
1700    /// assert_eq!(capacity, s.capacity());
1701    /// ```
1702    #[inline(always)]
1703    #[cfg(feature = "panic-on-alloc")]
1704    pub fn reserve_exact(&mut self, additional: usize) {
1705        panic_on_error(self.generic_reserve_exact(additional));
1706    }
1707
1708    /// Reserves the minimum capacity for at least `additional` bytes more than
1709    /// the current length. Unlike [`reserve`], this will not
1710    /// deliberately over-allocate to speculatively avoid frequent allocations.
1711    /// After calling `reserve_exact`, capacity will be greater than or equal to
1712    /// `self.len() + additional`. Does nothing if the capacity is already
1713    /// sufficient.
1714    ///
1715    /// [`reserve`]: Self::reserve
1716    ///
1717    /// # Errors
1718    /// Errors if the allocation fails.
1719    ///
1720    /// # Examples
1721    /// Basic usage:
1722    ///
1723    /// ```
1724    /// # use bump_scope::{Bump, MutBumpString};
1725    /// # let mut bump: Bump = Bump::new();
1726    /// let mut s = MutBumpString::new_in(&mut bump);
1727    ///
1728    /// s.try_reserve_exact(10)?;
1729    ///
1730    /// assert!(s.capacity() >= 10);
1731    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1732    /// ```
1733    ///
1734    /// This might not actually increase the capacity:
1735    ///
1736    /// ```
1737    /// # use bump_scope::{Bump, MutBumpString};
1738    /// # let mut bump: Bump = Bump::new();
1739    /// let mut s = MutBumpString::try_with_capacity_in(10, &mut bump)?;
1740    /// s.push('a');
1741    /// s.push('b');
1742    ///
1743    /// // s now has a length of 2 and a capacity of at least 10
1744    /// let capacity = s.capacity();
1745    /// assert_eq!(2, s.len());
1746    /// assert!(capacity >= 10);
1747    ///
1748    /// // Since we already have at least an extra 8 capacity, calling this...
1749    /// s.try_reserve_exact(8)?;
1750    ///
1751    /// // ... doesn't actually increase.
1752    /// assert_eq!(capacity, s.capacity());
1753    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1754    /// ```
1755    #[inline(always)]
1756    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), AllocError> {
1757        self.generic_reserve_exact(additional)
1758    }
1759
1760    #[inline]
1761    pub(crate) fn generic_reserve_exact<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
1762        let vec = unsafe { self.as_mut_vec() };
1763        vec.generic_reserve_exact(additional)
1764    }
1765
1766    unsafe fn insert_bytes<B: ErrorBehavior>(&mut self, idx: usize, bytes: &[u8]) -> Result<(), B> {
1767        unsafe {
1768            let vec = self.as_mut_vec();
1769
1770            let len = vec.len();
1771            let amt = bytes.len();
1772            vec.generic_reserve(amt)?;
1773
1774            ptr::copy(vec.as_ptr().add(idx), vec.as_mut_ptr().add(idx + amt), len - idx);
1775            ptr::copy_nonoverlapping(bytes.as_ptr(), vec.as_mut_ptr().add(idx), amt);
1776            vec.set_len(len + amt);
1777
1778            Ok(())
1779        }
1780    }
1781
1782    /// Returns a type which provides statistics about the memory usage of the bump allocator.
1783    ///
1784    /// This collection does not update the bump pointer, so it also doesn't contribute to the `remaining` and `allocated` stats.
1785    #[must_use]
1786    #[inline(always)]
1787    pub fn allocator_stats(&self) -> A::TypedStats<'_> {
1788        self.allocator.typed_stats()
1789    }
1790
1791    pub(crate) fn generic_write_fmt<B: ErrorBehavior>(&mut self, args: fmt::Arguments) -> Result<(), B> {
1792        #[cfg(feature = "panic-on-alloc")]
1793        if B::PANICS_ON_ALLOC {
1794            if fmt::Write::write_fmt(PanicsOnAlloc::from_mut(self), args).is_err() {
1795                // Our `PanicsOnAlloc` wrapped `Write` implementation panics on allocation failure.
1796                // So this can only be an error returned by a `fmt()` implementor.
1797                // Note that `fmt()` implementors *should* not return errors (see `std::fmt::Error`)
1798                return Err(B::format_trait_error());
1799            }
1800
1801            return Ok(());
1802        }
1803
1804        if fmt::Write::write_fmt(self, args).is_err() {
1805            // Either an allocation failed or the `fmt()` implementor returned an error.
1806            // Either way we return an `AllocError`.
1807            // Note that `fmt()` implementors *should* not return errors (see `std::fmt::Error`).
1808            // So it's fine not to have an extra error variant for that.
1809            return Err(B::format_trait_error());
1810        }
1811
1812        Ok(())
1813    }
1814}
1815
1816impl<'a, A: MutBumpAllocatorTypedScope<'a>> MutBumpString<A> {
1817    /// Converts this `MutBumpString` into `&str` that is live for this bump scope.
1818    ///
1819    /// Unused capacity does not take up space.<br/>
1820    /// When [bumping downwards](crate#bumping-upwards-or-downwards) this needs to shift all elements to the other end of the chunk.
1821    #[must_use]
1822    #[inline(always)]
1823    pub fn into_str(self) -> &'a mut str {
1824        self.into_boxed_str().into_mut()
1825    }
1826
1827    /// Converts a `MutBumpString` into a `BumpBox<str>`.
1828    ///
1829    /// Unused capacity does not take up space.<br/>
1830    /// When [bumping downwards](crate#bumping-upwards-or-downwards) this needs to shift all elements to the other end of the chunk.
1831    #[must_use]
1832    #[inline(always)]
1833    pub fn into_boxed_str(self) -> BumpBox<'a, str> {
1834        let bytes = self.into_bytes().into_boxed_slice();
1835        unsafe { BumpBox::from_utf8_unchecked(bytes) }
1836    }
1837
1838    /// Converts this `MutBumpString` into `&CStr` that is live for this bump scope.
1839    ///
1840    /// If the string contains a `'\0'` then the `CStr` will stop at the first `'\0'`.
1841    ///
1842    /// # Panics
1843    /// Panics if the allocation fails.
1844    ///
1845    /// # Examples
1846    /// ```
1847    /// # use bump_scope::{Bump, MutBumpString};
1848    /// # let mut bump: Bump = Bump::new();
1849    /// let hello = MutBumpString::from_str_in("Hello, world!", &mut bump);
1850    /// assert_eq!(hello.into_cstr(), c"Hello, world!");
1851    ///
1852    /// let abc0def = MutBumpString::from_str_in("abc\0def", &mut bump);
1853    /// assert_eq!(abc0def.into_cstr(), c"abc");
1854    /// ```
1855    #[must_use]
1856    #[inline(always)]
1857    #[cfg(feature = "panic-on-alloc")]
1858    pub fn into_cstr(self) -> &'a CStr {
1859        panic_on_error(self.generic_into_cstr())
1860    }
1861
1862    /// Converts this `MutBumpString` into `&CStr` that is live for this bump scope.
1863    ///
1864    /// If the string contains a `'\0'` then the `CStr` will stop at the first `'\0'`.
1865    ///
1866    /// # Errors
1867    /// Errors if the allocation fails.
1868    ///
1869    /// # Examples
1870    /// ```
1871    /// # use bump_scope::{Bump, MutBumpString};
1872    /// # let mut bump: Bump = Bump::new();
1873    /// let hello = MutBumpString::from_str_in("Hello, world!", &mut bump);
1874    /// assert_eq!(hello.into_cstr(), c"Hello, world!");
1875    ///
1876    /// let abc0def = MutBumpString::try_from_str_in("abc\0def", &mut bump)?;
1877    /// assert_eq!(abc0def.try_into_cstr()?, c"abc");
1878    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1879    /// ```
1880    #[inline(always)]
1881    pub fn try_into_cstr(self) -> Result<&'a CStr, AllocError> {
1882        self.generic_into_cstr()
1883    }
1884
1885    #[inline]
1886    pub(crate) fn generic_into_cstr<B: ErrorBehavior>(mut self) -> Result<&'a CStr, B> {
1887        match self.as_bytes().iter().position(|&c| c == b'\0') {
1888            Some(nul) => unsafe { self.fixed.cook_mut().as_mut_vec().truncate(nul + 1) },
1889            None => self.generic_push('\0')?,
1890        }
1891
1892        let bytes_with_nul = self.into_boxed_str().into_ref().as_bytes();
1893        Ok(unsafe { CStr::from_bytes_with_nul_unchecked(bytes_with_nul) })
1894    }
1895}
1896
1897impl<A: MutBumpAllocatorTyped> fmt::Write for MutBumpString<A> {
1898    #[inline(always)]
1899    fn write_str(&mut self, s: &str) -> fmt::Result {
1900        self.try_push_str(s).map_err(|_| fmt::Error)
1901    }
1902
1903    #[inline(always)]
1904    fn write_char(&mut self, c: char) -> fmt::Result {
1905        self.try_push(c).map_err(|_| fmt::Error)
1906    }
1907}
1908
1909#[cfg(feature = "panic-on-alloc")]
1910impl<A: MutBumpAllocatorTyped> fmt::Write for PanicsOnAlloc<MutBumpString<A>> {
1911    #[inline(always)]
1912    fn write_str(&mut self, s: &str) -> fmt::Result {
1913        self.0.push_str(s);
1914        Ok(())
1915    }
1916
1917    #[inline(always)]
1918    fn write_char(&mut self, c: char) -> fmt::Result {
1919        self.0.push(c);
1920        Ok(())
1921    }
1922}
1923
1924impl<A> Debug for MutBumpString<A> {
1925    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1926        Debug::fmt(self.as_str(), f)
1927    }
1928}
1929
1930impl<A> Display for MutBumpString<A> {
1931    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1932        Display::fmt(self.as_str(), f)
1933    }
1934}
1935
1936impl<A> Deref for MutBumpString<A> {
1937    type Target = str;
1938
1939    #[inline]
1940    fn deref(&self) -> &Self::Target {
1941        self.as_str()
1942    }
1943}
1944
1945impl<A> DerefMut for MutBumpString<A> {
1946    #[inline]
1947    fn deref_mut(&mut self) -> &mut Self::Target {
1948        self.as_mut_str()
1949    }
1950}
1951
1952impl<A, I: SliceIndex<str>> Index<I> for MutBumpString<A> {
1953    type Output = I::Output;
1954
1955    fn index(&self, index: I) -> &Self::Output {
1956        &self.as_str()[index]
1957    }
1958}
1959
1960impl<A, I: SliceIndex<str>> IndexMut<I> for MutBumpString<A> {
1961    fn index_mut(&mut self, index: I) -> &mut Self::Output {
1962        &mut self.as_mut_str()[index]
1963    }
1964}
1965
1966impl<A: Default> Default for MutBumpString<A> {
1967    fn default() -> Self {
1968        Self::new_in(A::default())
1969    }
1970}
1971
1972#[cfg(feature = "panic-on-alloc")]
1973impl<A: MutBumpAllocatorTyped> core::ops::AddAssign<&str> for MutBumpString<A> {
1974    #[inline]
1975    fn add_assign(&mut self, rhs: &str) {
1976        self.push_str(rhs);
1977    }
1978}
1979
1980impl<A> AsRef<str> for MutBumpString<A> {
1981    #[inline]
1982    fn as_ref(&self) -> &str {
1983        self.as_str()
1984    }
1985}
1986
1987impl<A> AsMut<str> for MutBumpString<A> {
1988    #[inline]
1989    fn as_mut(&mut self) -> &mut str {
1990        self.as_mut_str()
1991    }
1992}
1993
1994impl<A> Borrow<str> for MutBumpString<A> {
1995    #[inline]
1996    fn borrow(&self) -> &str {
1997        self.as_str()
1998    }
1999}
2000
2001impl<A> BorrowMut<str> for MutBumpString<A> {
2002    #[inline]
2003    fn borrow_mut(&mut self) -> &mut str {
2004        self.as_mut_str()
2005    }
2006}
2007
2008impl<A> Eq for MutBumpString<A> {}
2009
2010impl<A> PartialOrd for MutBumpString<A> {
2011    #[inline]
2012    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
2013        Some(self.cmp(other))
2014    }
2015
2016    #[inline]
2017    fn lt(&self, other: &Self) -> bool {
2018        <str as PartialOrd>::lt(self, other)
2019    }
2020
2021    #[inline]
2022    fn le(&self, other: &Self) -> bool {
2023        <str as PartialOrd>::le(self, other)
2024    }
2025
2026    #[inline]
2027    fn gt(&self, other: &Self) -> bool {
2028        <str as PartialOrd>::gt(self, other)
2029    }
2030
2031    #[inline]
2032    fn ge(&self, other: &Self) -> bool {
2033        <str as PartialOrd>::ge(self, other)
2034    }
2035}
2036
2037impl<A> Ord for MutBumpString<A> {
2038    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
2039        <str as Ord>::cmp(self, other)
2040    }
2041}
2042
2043impl<A> Hash for MutBumpString<A> {
2044    #[inline]
2045    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
2046        self.as_str().hash(state);
2047    }
2048}
2049
2050#[cfg(feature = "panic-on-alloc")]
2051impl<'s, A: MutBumpAllocatorTyped> Extend<&'s str> for MutBumpString<A> {
2052    #[inline]
2053    fn extend<T: IntoIterator<Item = &'s str>>(&mut self, iter: T) {
2054        for str in iter {
2055            self.push_str(str);
2056        }
2057    }
2058}
2059
2060#[cfg(feature = "panic-on-alloc")]
2061impl<A: MutBumpAllocatorTyped> Extend<char> for MutBumpString<A> {
2062    fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {
2063        let iterator = iter.into_iter();
2064        let (lower_bound, _) = iterator.size_hint();
2065        self.reserve(lower_bound);
2066        iterator.for_each(move |c| self.push(c));
2067    }
2068}
2069
2070#[cfg(feature = "panic-on-alloc")]
2071impl<'s, A: MutBumpAllocatorTyped> Extend<&'s char> for MutBumpString<A> {
2072    fn extend<I: IntoIterator<Item = &'s char>>(&mut self, iter: I) {
2073        self.extend(iter.into_iter().copied());
2074    }
2075}
2076
2077#[cfg(feature = "alloc")]
2078impl<A> From<MutBumpString<A>> for alloc_crate::string::String {
2079    #[inline]
2080    fn from(value: MutBumpString<A>) -> Self {
2081        value.as_str().into()
2082    }
2083}