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}