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