Skip to main content

utf8_bytes/
bytes_mut.rs

1use crate::FromUtf8Error;
2
3use super::Utf8Bytes;
4
5use core::iter::FromIterator;
6use core::mem::MaybeUninit;
7use core::ops::{Deref, DerefMut};
8use core::ptr::{self};
9use core::{cmp, fmt, hash};
10
11use alloc::{
12    borrow::{Borrow, BorrowMut},
13    string::String,
14    vec::Vec,
15};
16
17/// A unique reference to a contiguous slice of UTF-8 memory.
18///
19/// This is built on [`BytesMut`](bytes::BytesMut), see its documentation for more.
20pub struct Utf8BytesMut {
21    /// # Invariant
22    /// - contains UTF-8.
23    #[deprecated = "use the accessors to preserve the invariants"]
24    inner: bytes::BytesMut,
25}
26
27impl Utf8BytesMut {
28    /// Wrap `bytes` if it is UTF-8.
29    ///
30    /// If it is not, you can perform a lossy conversion using [`FromUtf8Error::into_utf8_lossy`].
31    pub fn from_bytes_mut(bytes: bytes::BytesMut) -> Result<Self, FromUtf8Error<bytes::BytesMut>> {
32        match str::from_utf8(&bytes) {
33            Ok(_) => Ok(unsafe { Self::from_bytes_mut_unchecked(bytes) }),
34            Err(error) => Err(FromUtf8Error { bytes, error }),
35        }
36    }
37    /// # Safety
38    /// `bytes` must only contain UTF-8.
39    pub const unsafe fn from_bytes_mut_unchecked(bytes: bytes::BytesMut) -> Self {
40        #[expect(deprecated)]
41        Self { inner: bytes }
42    }
43    /// Get the contents of the buffer.
44    pub fn as_str(&self) -> &str {
45        unsafe { str::from_utf8_unchecked(self.inner()) }
46    }
47    /// Get an exclusive reference to the contents of the buffer.
48    pub fn as_mut_str(&mut self) -> &mut str {
49        // SAFETY:
50        // - We don't modify the buffer except as a str.
51        // - The inner buffer satisfies our invariant.
52        unsafe { str::from_utf8_unchecked_mut(self.inner_mut_unchecked()) }
53    }
54}
55
56impl Utf8BytesMut {
57    /// Return a shared reference to the inner object.
58    #[inline]
59    pub const fn inner(&self) -> &bytes::BytesMut {
60        #[expect(deprecated)]
61        &self.inner
62    }
63
64    /// Return an exclusive reference to the inner object.
65    ///
66    /// # Safety
67    /// - The returned bytes must be returned containing UTF-8
68    #[inline]
69    pub const unsafe fn inner_mut_unchecked(&mut self) -> &mut bytes::BytesMut {
70        #[expect(deprecated)]
71        &mut self.inner
72    }
73    #[inline]
74    pub fn into_inner(self) -> bytes::BytesMut {
75        #[expect(deprecated)]
76        self.inner
77    }
78}
79
80impl Utf8BytesMut {
81    /// Creates a new [`Utf8BytesMut`] with the specified capacity.
82    ///
83    /// The returned [`Utf8BytesMut`] will be able to hold at least `capacity` bytes
84    /// without reallocating.
85    ///
86    /// # Examples
87    ///
88    /// ```
89    /// use utf8_bytes::Utf8BytesMut;
90    ///
91    /// let mut bytes = Utf8BytesMut::with_capacity(64);
92    ///
93    /// // `bytes` contains no data, even though there is capacity
94    /// assert_eq!(bytes.len(), 0);
95    ///
96    /// bytes.extend_from_str("hello world");
97    ///
98    /// assert_eq!(bytes, "hello world");
99    /// ```
100    #[inline]
101    pub fn with_capacity(capacity: usize) -> Utf8BytesMut {
102        unsafe { Self::from_bytes_mut_unchecked(bytes::BytesMut::with_capacity(capacity)) }
103    }
104
105    /// Creates a new `BytesMut` with default capacity.
106    ///
107    /// Resulting object has length 0 and unspecified capacity.
108    /// This function does not allocate.
109    ///
110    /// # Examples
111    ///
112    /// ```
113    /// use utf8_bytes::Utf8BytesMut;
114    ///
115    /// let mut bytes = Utf8BytesMut::new();
116    ///
117    /// assert_eq!(0, bytes.len());
118    ///
119    /// bytes.reserve(2);
120    /// bytes.extend_from_str("xy");
121    ///
122    /// assert_eq!("xy", bytes);
123    /// ```
124    #[inline]
125    pub fn new() -> Utf8BytesMut {
126        Utf8BytesMut::with_capacity(0)
127    }
128
129    /// Returns the number of bytes contained in this [`Utf8BytesMut`].
130    ///
131    /// # Examples
132    ///
133    /// ```
134    /// use utf8_bytes::Utf8BytesMut;
135    ///
136    /// let b = Utf8BytesMut::from("hello");
137    /// assert_eq!(b.len(), 5);
138    /// ```
139    #[inline]
140    pub fn len(&self) -> usize {
141        self.inner().len()
142    }
143
144    /// Returns true if the [`Utf8BytesMut`] has a length of 0.
145    ///
146    /// # Examples
147    ///
148    /// ```
149    /// use utf8_bytes::Utf8BytesMut;
150    ///
151    /// let b = Utf8BytesMut::with_capacity(64);
152    /// assert!(b.is_empty());
153    /// ```
154    #[inline]
155    pub fn is_empty(&self) -> bool {
156        self.inner().is_empty()
157    }
158
159    /// Returns the number of bytes the [`Utf8BytesMut`] can hold without reallocating.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use utf8_bytes::Utf8BytesMut;
165    ///
166    /// let b = Utf8BytesMut::with_capacity(64);
167    /// assert_eq!(b.capacity(), 64);
168    /// ```
169    #[inline]
170    pub fn capacity(&self) -> usize {
171        self.inner().capacity()
172    }
173
174    /// Converts `self` into an immutable [`Utf8Bytes`].
175    ///
176    /// The conversion is zero cost and is used to indicate that the slice
177    /// referenced by the handle will no longer be mutated. Once the conversion
178    /// is done, the handle can be cloned and shared across threads.
179    ///
180    /// # Examples
181    ///
182    /// ```
183    /// use utf8_bytes::{Utf8BytesMut};
184    /// use std::thread;
185    ///
186    /// let mut b = Utf8BytesMut::with_capacity(64);
187    /// b.extend_from_str("hello world");
188    /// let b1 = b.freeze();
189    /// let b2 = b1.clone();
190    ///
191    /// let th = thread::spawn(move || {
192    ///     assert_eq!(b1, "hello world");
193    /// });
194    ///
195    /// assert_eq!(b2, "hello world");
196    /// th.join().unwrap();
197    /// ```
198    #[inline]
199    pub fn freeze(self) -> Utf8Bytes {
200        // SAFETY:
201        // - contents is still UTF-8
202        unsafe { Utf8Bytes::from_bytes_unchecked(self.into_inner().freeze()) }
203    }
204
205    /// Creates a new [`Utf8BytesMut`] containing `len` zeros.
206    ///
207    /// The resulting object has a length of `len` and a capacity greater
208    /// than or equal to `len`. The entire length of the object will be filled
209    /// with zeros.
210    ///
211    /// On some platforms or allocators this function may be faster than
212    /// a manual implementation.
213    ///
214    /// # Examples
215    ///
216    /// ```
217    /// use utf8_bytes::Utf8BytesMut;
218    ///
219    /// let zeros = Utf8BytesMut::zeroed(42);
220    ///
221    /// assert!(zeros.capacity() >= 42);
222    /// assert_eq!(zeros.len(), 42);
223    /// zeros.chars().for_each(|ch| assert_eq!(ch, 0 as char));
224    /// ```
225    pub fn zeroed(len: usize) -> Utf8BytesMut {
226        // SAFETY:
227        // - null is valid UTF-8
228        unsafe { Self::from_bytes_mut_unchecked(bytes::BytesMut::zeroed(len)) }
229    }
230
231    /// Splits the [`Utf8BytesMut`] into two at the given index.
232    ///
233    /// Afterwards `self` contains elements `[0, at)`, and the returned
234    /// [`Utf8BytesMut`] contains elements `[at, capacity)`. It's guaranteed that the
235    /// memory does not move, that is, the address of `self` does not change,
236    /// and the address of the returned slice is `at` bytes after that.
237    ///
238    /// This is an `O(1)` operation that just increases the reference count
239    /// and sets a few indices.
240    ///
241    /// # Examples
242    ///
243    /// ```
244    /// use utf8_bytes::Utf8BytesMut;
245    ///
246    /// let mut a = Utf8BytesMut::from("hello world");
247    /// let mut b = a.split_off(5);
248    ///
249    /// assert_eq!(a, "hello");
250    /// assert_eq!(b, " world");
251    /// ```
252    ///
253    /// # Panics
254    ///
255    /// - If `at > capacity`.
256    /// - If `at` does not lie on a character boundary.
257    #[must_use = "consider Utf8BytesMut::truncate if you don't need the other half"]
258    #[track_caller]
259    pub fn split_off(&mut self, at: usize) -> Utf8BytesMut {
260        let _char_boundary = self.as_str().split_at(at);
261        // SAFETY:
262        // - checked UTF-8 above!
263        unsafe { Self::from_bytes_mut_unchecked(self.inner_mut_unchecked().split_off(at)) }
264    }
265
266    /// Removes the bytes from the current view, returning them in a new
267    /// [`Utf8BytesMut`] handle.
268    ///
269    /// Afterwards, `self` will be empty, but will retain any additional
270    /// capacity that it had before the operation. This is identical to
271    /// `self.split_to(self.len())`.
272    ///
273    /// This is an `O(1)` operation that just increases the reference count and
274    /// sets a few indices.
275    ///
276    /// # Examples
277    ///
278    /// ```
279    /// use utf8_bytes::Utf8BytesMut;
280    ///
281    /// let mut buf = Utf8BytesMut::with_capacity(1024);
282    /// buf.extend_from_str("hello world");
283    ///
284    /// let other = buf.split();
285    ///
286    /// assert!(buf.is_empty());
287    /// assert_eq!(1013, buf.capacity());
288    ///
289    /// assert_eq!(other, "hello world");
290    /// ```
291    #[must_use = "consider Utf8BytesMut::clear if you don't need the other half"]
292    pub fn split(&mut self) -> Utf8BytesMut {
293        // SAFETY:
294        // - empty is valid UTF-8.
295        unsafe { Self::from_bytes_mut_unchecked(self.inner_mut_unchecked().split()) }
296    }
297
298    /// Splits the buffer into two at the given index.
299    ///
300    /// Afterwards `self` contains elements `[at, len)`, and the returned [`Utf8BytesMut`]
301    /// contains elements `[0, at)`.
302    ///
303    /// This is an `O(1)` operation that just increases the reference count and
304    /// sets a few indices.
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// use utf8_bytes::Utf8BytesMut;
310    ///
311    /// let mut a = Utf8BytesMut::from("hello world");
312    /// let mut b = a.split_to(5);
313    ///
314    /// b[1..].make_ascii_uppercase();
315    /// a[2..].make_ascii_uppercase();
316    ///
317    /// assert_eq!(&a[..], " wORLD");
318    /// assert_eq!(&b[..], "hELLO");
319    /// ```
320    ///
321    /// # Panics
322    ///
323    /// - If `at > len`.
324    /// - If `at` is not on a char boundary.
325    #[must_use = "consider Utf8BytesMut::advance if you don't need the other half"]
326    #[track_caller]
327    pub fn split_to(&mut self, at: usize) -> Utf8BytesMut {
328        let _char_boundary = self.as_str().split_at(at);
329        // SAFETY:
330        // - checked UTF-8 above
331        unsafe { Self::from_bytes_mut_unchecked(self.inner_mut_unchecked().split_to(at)) }
332    }
333
334    /// Shortens the buffer, keeping the first `len` bytes and dropping the
335    /// rest.
336    ///
337    /// If `len` is greater than the buffer's current length, this has no
338    /// effect.
339    ///
340    /// Existing underlying capacity is preserved.
341    ///
342    /// The [split_off](`Self::split_off()`) method can emulate `truncate`, but this causes the
343    /// excess bytes to be returned instead of dropped.
344    ///
345    /// # Examples
346    ///
347    /// ```
348    /// use utf8_bytes::Utf8BytesMut;
349    ///
350    /// let mut buf = Utf8BytesMut::from("hello world");
351    /// buf.truncate(5);
352    /// assert_eq!(buf, "hello");
353    /// ```
354    ///
355    /// # Panics
356    /// - If `len` is not on a char boundary.
357    pub fn truncate(&mut self, len: usize) {
358        if len < self.len() {
359            let _char_boundary = self.as_str().split_at(len);
360            // SAFETY:
361            // - checked on boundary above
362            unsafe { self.inner_mut_unchecked().truncate(len) };
363        };
364    }
365
366    /// Clears the buffer, removing all data. Existing capacity is preserved.
367    ///
368    /// # Examples
369    ///
370    /// ```
371    /// use utf8_bytes::Utf8BytesMut;
372    ///
373    /// let mut buf = Utf8BytesMut::from("hello world");
374    /// buf.clear();
375    /// assert!(buf.is_empty());
376    /// ```
377    pub fn clear(&mut self) {
378        // SAFETY:
379        // - empty is valid UTF-8
380        unsafe { self.inner_mut_unchecked().clear() };
381    }
382
383    /// Resizes the buffer so that `len` is equal to `new_len`.
384    ///
385    /// If `new_len` is greater than `len`, the buffer is extended by the
386    /// difference with each additional byte set to `value`. If `new_len` is
387    /// less than `len`, the buffer is simply truncated.
388    ///
389    /// # Examples
390    ///
391    /// ```
392    /// use utf8_bytes::Utf8BytesMut;
393    ///
394    /// let mut buf = Utf8BytesMut::new();
395    ///
396    /// buf.resize(3, b'A');
397    /// assert_eq!(&buf[..], "AAA");
398    ///
399    /// buf.resize(2, b'B');
400    /// assert_eq!(&buf[..], "AA");
401    ///
402    /// buf.resize(4, b'C');
403    /// assert_eq!(&buf[..], "AACC");
404    /// ```
405    ///
406    /// # Panics
407    /// - If `new_len` is shorter than [`Self::len`] and does not lie on a char boundary.
408    pub fn resize(&mut self, new_len: usize, ch: u8) {
409        assert!(ch.is_ascii());
410        let additional = if let Some(additional) = new_len.checked_sub(self.len()) {
411            additional
412        } else {
413            self.truncate(new_len);
414            return;
415        };
416
417        if additional == 0 {
418            return;
419        }
420
421        self.reserve(additional);
422        let dst = self.spare_capacity_mut().as_mut_ptr();
423        // SAFETY: `spare_capacity_mut` returns a valid, properly aligned pointer and we've
424        // reserved enough space to write `additional` bytes.
425        unsafe { ptr::write_bytes(dst, ch, additional) };
426
427        // SAFETY: There are at least `new_len` initialized bytes in the buffer so no
428        // uninitialized bytes are being exposed.
429        unsafe { self.set_len(new_len) };
430    }
431
432    /// Sets the length of the buffer.
433    ///
434    /// This will explicitly set the size of the buffer without actually
435    /// modifying the data, so it is up to the caller to ensure that the data
436    /// has been initialized.
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// use utf8_bytes::Utf8BytesMut;
442    ///
443    /// let mut b = Utf8BytesMut::from("hello world");
444    ///
445    /// unsafe {
446    ///     b.set_len(5);
447    /// }
448    ///
449    /// assert_eq!(&b[..], "hello");
450    ///
451    /// unsafe {
452    ///     b.set_len(11);
453    /// }
454    ///
455    /// assert_eq!(&b[..], "hello world");
456    /// ```
457    ///
458    /// # Safety
459    /// - Data up to `len` must be initialized with valid UTF-8.
460    #[inline]
461    pub unsafe fn set_len(&mut self, len: usize) {
462        unsafe { self.inner_mut_unchecked().set_len(len) }
463    }
464
465    /// Reserves capacity for at least `additional` more bytes to be inserted
466    /// into the given [`Utf8BytesMut`].
467    ///
468    /// More than `additional` bytes may be reserved in order to avoid frequent
469    /// reallocations. A call to `reserve` may result in an allocation.
470    ///
471    /// Before allocating new buffer space, the function will attempt to reclaim
472    /// space in the existing buffer. If the current handle references a view
473    /// into a larger original buffer, and all other handles referencing part
474    /// of the same original buffer have been dropped, then the current view
475    /// can be copied/shifted to the front of the buffer and the handle can take
476    /// ownership of the full buffer, provided that the full buffer is large
477    /// enough to fit the requested additional capacity.
478    ///
479    /// This optimization will only happen if shifting the data from the current
480    /// view to the front of the buffer is not too expensive in terms of the
481    /// (amortized) time required. The precise condition is subject to change;
482    /// as of now, the length of the data being shifted needs to be at least as
483    /// large as the distance that it's shifted by. If the current view is empty
484    /// and the original buffer is large enough to fit the requested additional
485    /// capacity, then reallocations will never happen.
486    ///
487    /// # Examples
488    ///
489    /// In the following example, a new buffer is allocated.
490    ///
491    /// ```
492    /// use utf8_bytes::Utf8BytesMut;
493    ///
494    /// let mut buf = Utf8BytesMut::from("hello");
495    /// buf.reserve(64);
496    /// assert!(buf.capacity() >= 69);
497    /// ```
498    ///
499    /// In the following example, the existing buffer is reclaimed.
500    ///
501    /// ```
502    /// use utf8_bytes::{Utf8BytesMut};
503    ///
504    /// let mut buf = Utf8BytesMut::with_capacity(128);
505    /// buf.extend_from_str(str::from_utf8(&[0; 64]).unwrap());
506    ///
507    /// let ptr = buf.as_ptr();
508    /// let other = buf.split();
509    ///
510    /// assert!(buf.is_empty());
511    /// assert_eq!(buf.capacity(), 64);
512    ///
513    /// drop(other);
514    /// buf.reserve(128);
515    ///
516    /// assert_eq!(buf.capacity(), 128);
517    /// assert_eq!(buf.as_ptr(), ptr);
518    /// ```
519    ///
520    /// # Panics
521    ///
522    /// Panics if the new capacity overflows `usize`.
523    #[inline]
524    pub fn reserve(&mut self, additional: usize) {
525        // SAFETY:
526        // - does not change logical contents
527        unsafe { self.inner_mut_unchecked() }.reserve(additional);
528    }
529
530    /// Attempts to cheaply reclaim already allocated capacity for at least `additional` more
531    /// bytes to be inserted into the given [`Utf8BytesMut`] and returns `true` if it succeeded.
532    ///
533    /// `try_reclaim` behaves exactly like `reserve`, except that it never allocates new storage
534    /// and returns a `bool` indicating whether it was successful in doing so:
535    ///
536    /// `try_reclaim` returns false under these conditions:
537    ///  - The spare capacity left is less than `additional` bytes AND
538    ///  - The existing allocation cannot be reclaimed cheaply or it was less than
539    ///    `additional` bytes in size
540    ///
541    /// Reclaiming the allocation cheaply is possible if the [`Utf8BytesMut`] has no outstanding
542    /// references through other [`Utf8BytesMut`]s or `Bytes` which point to the same underlying
543    /// storage.
544    ///
545    /// # Examples
546    ///
547    /// ```
548    /// use utf8_bytes::Utf8BytesMut;
549    ///
550    /// let mut buf = Utf8BytesMut::with_capacity(64);
551    /// assert_eq!(true, buf.try_reclaim(64));
552    /// assert_eq!(64, buf.capacity());
553    ///
554    /// buf.extend_from_str("abcd");
555    /// let mut split = buf.split();
556    /// assert_eq!(60, buf.capacity());
557    /// assert_eq!(4, split.capacity());
558    /// assert_eq!(false, split.try_reclaim(64));
559    /// assert_eq!(false, buf.try_reclaim(64));
560    /// // The split buffer is filled with "abcd"
561    /// assert_eq!(false, split.try_reclaim(4));
562    /// // buf is empty and has capacity for 60 bytes
563    /// assert_eq!(true, buf.try_reclaim(60));
564    ///
565    /// drop(buf);
566    /// assert_eq!(false, split.try_reclaim(64));
567    ///
568    /// split.clear();
569    /// assert_eq!(4, split.capacity());
570    /// assert_eq!(true, split.try_reclaim(64));
571    /// assert_eq!(64, split.capacity());
572    /// ```
573    // I tried splitting out try_reclaim_inner after the short circuits, but it was inlined
574    // regardless with Rust 1.78.0 so probably not worth it
575    #[inline]
576    #[must_use = "consider BytesMut::reserve if you need an infallible reservation"]
577    pub fn try_reclaim(&mut self, additional: usize) -> bool {
578        // SAFETY:
579        // - does not modify logical contents
580        unsafe { self.inner_mut_unchecked() }.try_reclaim(additional)
581    }
582
583    /// Appends given bytes to this [`Utf8BytesMut`].
584    ///
585    /// If this [`Utf8BytesMut`] object does not have enough capacity, it is resized
586    /// first.
587    ///
588    /// # Examples
589    ///
590    /// ```
591    /// use utf8_bytes::Utf8BytesMut;
592    ///
593    /// let mut buf = Utf8BytesMut::with_capacity(0);
594    /// buf.extend_from_str("aaabbb");
595    /// buf.extend_from_str("cccddd");
596    ///
597    /// assert_eq!("aaabbbcccddd", &buf[..]);
598    /// ```
599    #[inline]
600    pub fn extend_from_str(&mut self, extend: &str) {
601        // SAFETY:
602        // - extend: &str
603        unsafe { self.inner_mut_unchecked() }.extend_from_slice(extend.as_bytes());
604    }
605
606    /// Absorbs a [`Utf8BytesMut`] that was previously split off.
607    ///
608    /// If the two [`Utf8BytesMut`] objects were previously contiguous and not mutated
609    /// in a way that causes re-allocation i.e., if `other` was created by
610    /// calling `split_off` on this [`Utf8BytesMut`], then this is an `O(1)` operation
611    /// that just decreases a reference count and sets a few indices.
612    /// Otherwise this method degenerates to
613    /// `self.extend_from_slice(other.as_ref())`.
614    ///
615    /// # Examples
616    ///
617    /// ```
618    /// use utf8_bytes::Utf8BytesMut;
619    ///
620    /// let mut buf = Utf8BytesMut::with_capacity(64);
621    /// buf.extend_from_str("aaabbbcccddd");
622    ///
623    /// let split = buf.split_off(6);
624    /// assert_eq!("aaabbb", &buf[..]);
625    /// assert_eq!("cccddd", &split[..]);
626    ///
627    /// buf.unsplit(split);
628    /// assert_eq!("aaabbbcccddd", &buf[..]);
629    /// ```
630    pub fn unsplit(&mut self, other: Utf8BytesMut) {
631        // SAFETY:
632        // - both buffers are UTF-8, and concatenating UTF-8 is safe.
633        unsafe { self.inner_mut_unchecked() }.unsplit(other.into_inner());
634    }
635
636    /// Returns the remaining spare capacity of the buffer as a slice of `MaybeUninit<u8>`.
637    ///
638    /// The returned slice can be used to fill the buffer with data (e.g. by
639    /// reading from a file) before marking the data as initialized using the
640    /// [`set_len`] method.
641    ///
642    /// [`set_len`]: Utf8BytesMut::set_len
643    ///
644    /// # Examples
645    ///
646    /// ```
647    /// use utf8_bytes::Utf8BytesMut;
648    ///
649    /// // Allocate buffer big enough for 10 bytes.
650    /// let mut buf = Utf8BytesMut::with_capacity(10);
651    ///
652    /// // Fill in the first 3 elements.
653    /// let uninit = buf.spare_capacity_mut();
654    /// uninit[0].write(b'A');
655    /// uninit[1].write(b'B');
656    /// uninit[2].write(b'C');
657    ///
658    /// // Mark the first 3 bytes of the buffer as being initialized.
659    /// unsafe {
660    ///     buf.set_len(3);
661    /// }
662    ///
663    /// assert_eq!(&buf[..], "ABC");
664    /// ```
665    #[inline]
666    pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
667        // SAFETY:
668        // - does not logically modify contents
669        unsafe { self.inner_mut_unchecked() }.spare_capacity_mut()
670    }
671}
672
673impl fmt::Debug for Utf8BytesMut {
674    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
675        self.as_str().fmt(f)
676    }
677}
678
679impl fmt::Display for Utf8BytesMut {
680    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
681        self.as_str().fmt(f)
682    }
683}
684
685impl AsRef<[u8]> for Utf8BytesMut {
686    #[inline]
687    fn as_ref(&self) -> &[u8] {
688        self.as_str().as_bytes()
689    }
690}
691
692impl AsRef<str> for Utf8BytesMut {
693    fn as_ref(&self) -> &str {
694        self.as_str()
695    }
696}
697
698impl Deref for Utf8BytesMut {
699    type Target = str;
700
701    #[inline]
702    fn deref(&self) -> &str {
703        self.as_str()
704    }
705}
706
707impl AsMut<str> for Utf8BytesMut {
708    #[inline]
709    fn as_mut(&mut self) -> &mut str {
710        self.as_mut_str()
711    }
712}
713
714impl DerefMut for Utf8BytesMut {
715    #[inline]
716    fn deref_mut(&mut self) -> &mut str {
717        self.as_mut_str()
718    }
719}
720
721impl<'a> From<&'a str> for Utf8BytesMut {
722    fn from(src: &'a str) -> Utf8BytesMut {
723        unsafe { Self::from_bytes_mut_unchecked(src.as_bytes().into()) }
724    }
725}
726
727impl From<Utf8BytesMut> for Utf8Bytes {
728    fn from(src: Utf8BytesMut) -> Utf8Bytes {
729        src.freeze()
730    }
731}
732
733impl From<Utf8BytesMut> for bytes::BytesMut {
734    fn from(src: Utf8BytesMut) -> bytes::BytesMut {
735        src.into_inner()
736    }
737}
738
739impl<T: AsRef<str>> PartialEq<T> for Utf8BytesMut {
740    fn eq(&self, other: &T) -> bool {
741        self.as_str().eq(other.as_ref())
742    }
743}
744
745impl Eq for Utf8BytesMut {}
746
747impl<T: AsRef<str>> PartialOrd<T> for Utf8BytesMut {
748    fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
749        self.as_str().partial_cmp(other.as_ref())
750    }
751}
752
753impl Ord for Utf8BytesMut {
754    fn cmp(&self, other: &Utf8BytesMut) -> cmp::Ordering {
755        self.as_str().cmp(other.as_str())
756    }
757}
758
759impl Default for Utf8BytesMut {
760    #[inline]
761    fn default() -> Utf8BytesMut {
762        Utf8BytesMut::new()
763    }
764}
765
766impl hash::Hash for Utf8BytesMut {
767    fn hash<H>(&self, state: &mut H)
768    where
769        H: hash::Hasher,
770    {
771        self.as_str().hash(state);
772    }
773}
774
775impl Borrow<str> for Utf8BytesMut {
776    fn borrow(&self) -> &str {
777        self.as_str()
778    }
779}
780
781impl BorrowMut<str> for Utf8BytesMut {
782    fn borrow_mut(&mut self) -> &mut str {
783        self.as_mut_str()
784    }
785}
786
787impl fmt::Write for Utf8BytesMut {
788    #[inline]
789    fn write_str(&mut self, s: &str) -> fmt::Result {
790        // SAFETY:
791        // - s: &str
792        unsafe { self.inner_mut_unchecked() }.write_str(s)
793    }
794
795    #[inline]
796    fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
797        // SAFETY:
798        // - args emit UTF-8
799        unsafe { self.inner_mut_unchecked() }.write_fmt(args)
800    }
801}
802
803impl Clone for Utf8BytesMut {
804    fn clone(&self) -> Utf8BytesMut {
805        Utf8BytesMut::from(&self[..])
806    }
807}
808
809impl Extend<char> for Utf8BytesMut {
810    fn extend<T>(&mut self, iter: T)
811    where
812        T: IntoIterator<Item = char>,
813    {
814        let iter = iter.into_iter();
815
816        let (lower, _) = iter.size_hint();
817        self.reserve(lower);
818
819        for c in iter {
820            fmt::Write::write_char(self, c).unwrap()
821        }
822    }
823}
824
825impl<'a> Extend<&'a char> for Utf8BytesMut {
826    fn extend<T>(&mut self, iter: T)
827    where
828        T: IntoIterator<Item = &'a char>,
829    {
830        self.extend(iter.into_iter().copied())
831    }
832}
833
834impl Extend<Utf8Bytes> for Utf8BytesMut {
835    fn extend<T>(&mut self, iter: T)
836    where
837        T: IntoIterator<Item = Utf8Bytes>,
838    {
839        for bytes in iter {
840            self.extend_from_str(&bytes)
841        }
842    }
843}
844
845impl FromIterator<char> for Utf8BytesMut {
846    fn from_iter<T: IntoIterator<Item = char>>(into_iter: T) -> Self {
847        unsafe {
848            Self::from_bytes_mut_unchecked(
849                String::from_iter(into_iter)
850                    .into_bytes()
851                    .into_iter()
852                    .collect(),
853            )
854        }
855    }
856}
857
858impl<'a> FromIterator<&'a char> for Utf8BytesMut {
859    fn from_iter<T: IntoIterator<Item = &'a char>>(into_iter: T) -> Self {
860        Self::from_iter(into_iter.into_iter().copied())
861    }
862}
863
864/*
865 *
866 * ===== PartialEq / PartialOrd =====
867 *
868 */
869
870impl PartialEq<[u8]> for Utf8BytesMut {
871    fn eq(&self, other: &[u8]) -> bool {
872        self.as_str().as_bytes() == other
873    }
874}
875
876impl PartialOrd<[u8]> for Utf8BytesMut {
877    fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
878        self.as_str().as_bytes().partial_cmp(other)
879    }
880}
881
882impl PartialEq<Utf8BytesMut> for [u8] {
883    fn eq(&self, other: &Utf8BytesMut) -> bool {
884        *other == *self
885    }
886}
887
888impl PartialOrd<Utf8BytesMut> for [u8] {
889    fn partial_cmp(&self, other: &Utf8BytesMut) -> Option<cmp::Ordering> {
890        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other.as_bytes())
891    }
892}
893
894impl PartialEq<str> for Utf8BytesMut {
895    fn eq(&self, other: &str) -> bool {
896        &**self == other
897    }
898}
899
900impl PartialOrd<str> for Utf8BytesMut {
901    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
902        (**self).partial_cmp(other)
903    }
904}
905
906impl PartialEq<Utf8BytesMut> for str {
907    fn eq(&self, other: &Utf8BytesMut) -> bool {
908        *other == *self
909    }
910}
911
912impl PartialOrd<Utf8BytesMut> for str {
913    fn partial_cmp(&self, other: &Utf8BytesMut) -> Option<cmp::Ordering> {
914        <str as PartialOrd<str>>::partial_cmp(self, other)
915    }
916}
917
918impl PartialEq<Utf8BytesMut> for Vec<u8> {
919    fn eq(&self, other: &Utf8BytesMut) -> bool {
920        self == other.as_bytes()
921    }
922}
923
924impl PartialEq<Utf8BytesMut> for String {
925    fn eq(&self, other: &Utf8BytesMut) -> bool {
926        *other == *self
927    }
928}
929
930impl PartialOrd<Utf8BytesMut> for String {
931    fn partial_cmp(&self, other: &Utf8BytesMut) -> Option<cmp::Ordering> {
932        <str as PartialOrd<str>>::partial_cmp(self, other)
933    }
934}
935
936impl PartialEq<Utf8BytesMut> for &[u8] {
937    fn eq(&self, other: &Utf8BytesMut) -> bool {
938        *self == other.as_bytes()
939    }
940}
941
942impl PartialOrd<Utf8BytesMut> for &[u8] {
943    fn partial_cmp(&self, other: &Utf8BytesMut) -> Option<cmp::Ordering> {
944        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other.as_bytes())
945    }
946}
947
948impl PartialEq<Utf8BytesMut> for &str {
949    fn eq(&self, other: &Utf8BytesMut) -> bool {
950        *self == other.as_str()
951    }
952}
953
954impl PartialOrd<Utf8BytesMut> for &str {
955    fn partial_cmp(&self, other: &Utf8BytesMut) -> Option<cmp::Ordering> {
956        other.partial_cmp(self)
957    }
958}
959
960impl PartialEq<Utf8BytesMut> for bytes::Bytes {
961    fn eq(&self, other: &Utf8BytesMut) -> bool {
962        self == other.as_bytes()
963    }
964}
965
966impl From<Utf8BytesMut> for Vec<u8> {
967    fn from(value: Utf8BytesMut) -> Self {
968        value.into_inner().into()
969    }
970}
971
972impl From<Utf8BytesMut> for String {
973    fn from(bytes: Utf8BytesMut) -> Self {
974        // SAFETY:
975        // - bytes is UTF-8
976        unsafe { Self::from_utf8_unchecked(Vec::from(bytes.into_inner())) }
977    }
978}
979
980impl From<String> for Utf8BytesMut {
981    fn from(value: String) -> Self {
982        // SAFETY:
983        // - value is UTF-8
984        unsafe { Self::from_bytes_mut_unchecked(value.into_bytes().into_iter().collect()) }
985    }
986}