Skip to main content

smol_bytes/
bytes_mut.rs

1use core::mem::MaybeUninit;
2
3use ::bytes::BufMut;
4use bytes::Buf;
5
6use crate::{INLINE_CAP, InvalidIntegerLength, OutOfBounds, buffer::Buffer, bytes::RawBytes};
7
8mod cmp;
9mod fmt;
10mod from;
11mod iter;
12mod ops;
13
14#[cfg(feature = "arbitrary")]
15mod arbitrary;
16#[cfg(feature = "borsh")]
17mod borsh;
18#[cfg(feature = "quickcheck")]
19mod quickcheck;
20#[cfg(feature = "serde")]
21mod serde;
22
23#[cfg(feature = "pyo3")]
24mod python;
25
26#[cfg(feature = "wasm")]
27mod wasm;
28
29#[doc = "Growable mutable byte buffer with inline/heap storage."]
30#[doc = ""]
31#[doc = "Stores up to 62 bytes inline on the stack. Larger data automatically"]
32#[doc = "promotes to heap allocation. Once on heap, stays on heap."]
33#[cfg_attr(not(feature = "wasm"), doc = "")]
34#[cfg_attr(not(feature = "wasm"), doc = "# Inline vs Heap Storage")]
35#[cfg_attr(not(feature = "wasm"), doc = "")]
36#[cfg_attr(
37  not(feature = "wasm"),
38  doc = "- **Inline**: Buffers ≤62 bytes are stored directly in the `BytesMut` struct"
39)]
40#[cfg_attr(
41  not(feature = "wasm"),
42  doc = "- **Heap**: Buffers >62 bytes are automatically promoted to heap allocation"
43)]
44#[cfg_attr(
45  not(feature = "wasm"),
46  doc = "- Once promoted to heap, the buffer stays on the heap (no automatic demotion)"
47)]
48#[cfg_attr(not(feature = "wasm"), doc = "")]
49#[cfg_attr(not(feature = "wasm"), doc = "# Split Operations")]
50#[cfg_attr(not(feature = "wasm"), doc = "")]
51#[cfg_attr(
52  not(feature = "wasm"),
53  doc = "Split operations have different behavior based on storage type:"
54)]
55#[cfg_attr(
56  not(feature = "wasm"),
57  doc = "- [`split_off`](Self::split_off): Returns `Ok(BytesMut)` for heap, `Err(Buffer)` for inline"
58)]
59#[cfg_attr(
60  not(feature = "wasm"),
61  doc = "- [`split_to`](Self::split_to): Returns `Ok(BytesMut)` for heap, `Err(Buffer)` for inline"
62)]
63#[cfg_attr(
64  not(feature = "wasm"),
65  doc = "- [`split`](Self::split): Returns `Ok(BytesMut)` for heap, `Err(Buffer)` for inline"
66)]
67#[cfg_attr(
68  not(feature = "wasm"),
69  doc = "- [`unsplit`](Self::unsplit): Only works when both buffers are heap-allocated"
70)]
71#[cfg_attr(not(feature = "wasm"), doc = "")]
72#[cfg_attr(not(feature = "wasm"), doc = "## Examples")]
73#[cfg_attr(not(feature = "wasm"), doc = "")]
74#[cfg_attr(not(feature = "wasm"), doc = "```")]
75#[cfg_attr(not(feature = "wasm"), doc = "use smol_bytes::BytesMut;")]
76#[cfg_attr(not(feature = "wasm"), doc = "")]
77#[cfg_attr(
78  not(feature = "wasm"),
79  doc = "let mut buf = BytesMut::from(&b\"hello\"[..]);"
80)]
81#[cfg_attr(not(feature = "wasm"), doc = "assert!(buf.is_inline());")]
82#[cfg_attr(not(feature = "wasm"), doc = "```")]
83#[cfg_attr(feature = "wasm", doc = "")]
84#[cfg_attr(feature = "wasm", doc = "@example")]
85#[cfg_attr(feature = "wasm", doc = "```typescript")]
86#[cfg_attr(feature = "wasm", doc = "import { BytesMut } from 'smol-bytes';")]
87#[cfg_attr(feature = "wasm", doc = "const buf = BytesMut.withCapacity(100);")]
88#[cfg_attr(feature = "wasm", doc = "buf.putSlice(new Uint8Array([1, 2, 3]));")]
89#[cfg_attr(feature = "wasm", doc = "console.log(buf.len()); // 3")]
90#[cfg_attr(feature = "wasm", doc = "```")]
91#[derive(Clone)]
92#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(from_py_object))]
93#[cfg_attr(feature = "wasm", wasm_bindgen::prelude::wasm_bindgen)]
94pub struct BytesMut(Repr);
95
96impl Default for BytesMut {
97  #[cfg_attr(not(coverage), inline(always))]
98  fn default() -> Self {
99    Self::new()
100  }
101}
102
103impl BytesMut {
104  #[cfg_attr(not(coverage), inline(always))]
105  pub(crate) fn from_bytes(bytes: bytes::Bytes) -> Self {
106    if !bytes.is_unique() && bytes.len() <= INLINE_CAP {
107      // SAFETY: bytes.len() is guaranteed to be less than or equal to INLINE_CAP
108      return Self(Repr::Inline(unsafe { Buffer::copy_from_slice(&bytes) }));
109    }
110
111    Self(Repr::Heap(bytes.into()))
112  }
113
114  #[cfg_attr(not(coverage), inline(always))]
115  pub(crate) fn from_bytes_mut(bytes: bytes::BytesMut) -> Self {
116    Self(Repr::Heap(bytes))
117  }
118
119  #[cfg_attr(not(coverage), inline(always))]
120  pub(crate) fn from_inline(bytes: Buffer) -> Self {
121    Self(Repr::Inline(bytes))
122  }
123}
124
125impl BytesMut {
126  /// Creates a new `BytesMut` containing `len` zeros.
127  ///
128  /// The resulting object has a length of `len` and a capacity greater
129  /// than or equal to `len`. The entire length of the object will be filled
130  /// with zeros.
131  ///
132  /// On some platforms or allocators this function may be faster than
133  /// a manual implementation.
134  ///
135  /// ## Examples
136  ///
137  /// ```
138  /// use smol_bytes::BytesMut;
139  ///
140  /// let zeros = BytesMut::zeroed(42);
141  ///
142  /// assert!(zeros.capacity() >= 42);
143  /// assert_eq!(zeros.len(), 42);
144  /// zeros.into_iter().for_each(|x| assert_eq!(x, 0));
145  /// ```
146  pub fn zeroed(len: usize) -> Self {
147    if len <= INLINE_CAP {
148      // SAFETY: len is guaranteed to be less than or equal to INLINE_CAP
149      Self(Repr::Inline(unsafe { Buffer::zeroed(len) }))
150    } else {
151      Self(Repr::Heap(bytes::BytesMut::zeroed(len)))
152    }
153  }
154
155  /// Creates a new, empty `BytesMut`.
156  ///
157  /// ## Example
158  ///
159  /// ```rust
160  /// use smol_bytes::BytesMut;
161  ///
162  /// let bytes = BytesMut::new();
163  /// assert_eq!(bytes.len(), 0);
164  /// ```
165  #[cfg_attr(not(coverage), inline(always))]
166  pub const fn new() -> Self {
167    Self(Repr::Inline(Buffer::new()))
168  }
169
170  /// Creates a new `BytesMut` with the specified capacity.
171  ///
172  /// The returned `BytesMut` will be able to hold at least capacity bytes without reallocating.
173  ///
174  /// It is important to note that this function does not specify the length of the returned BytesMut, but only the capacity.
175  #[cfg_attr(not(coverage), inline(always))]
176  pub fn with_capacity(capacity: usize) -> Self {
177    if capacity <= INLINE_CAP {
178      Self(Repr::Inline(Buffer::new()))
179    } else {
180      Self(Repr::Heap(bytes::BytesMut::with_capacity(capacity)))
181    }
182  }
183
184  /// Appends given bytes to this `BytesMut`.
185  ///
186  /// If this `BytesMut` object does not have enough capacity, it is resized
187  /// first.
188  ///
189  /// ## Examples
190  ///
191  /// ```
192  /// use smol_bytes::BytesMut;
193  ///
194  /// let mut buf = BytesMut::with_capacity(0);
195  /// buf.extend_from_slice(b"aaabbb");
196  /// buf.extend_from_slice(b"cccddd");
197  ///
198  /// assert_eq!(b"aaabbbcccddd", &buf[..]);
199  /// ```
200  #[inline]
201  pub fn extend_from_slice(&mut self, extend: &[u8]) {
202    match &mut self.0 {
203      Repr::Inline(b) => {
204        let requested = extend.len();
205        if b.try_reclaim(requested) {
206          b.put_slice(extend);
207          return;
208        }
209
210        let required = b.len().checked_add(requested).expect("capacity overflow");
211        let mut new_buf = bytes::BytesMut::with_capacity(required);
212        new_buf.put_slice(b.as_slice());
213        new_buf.extend_from_slice(extend);
214        self.0 = Repr::Heap(new_buf);
215      }
216      Repr::Heap(b) => b.extend_from_slice(extend),
217    }
218  }
219
220  /// Clears the buffer, removing all data. Existing capacity is preserved.
221  ///
222  /// ## Example
223  ///
224  /// ```rust
225  /// use smol_bytes::BytesMut;
226  ///
227  /// let mut bytes = BytesMut::from(&b"hello world"[..]);
228  /// bytes.clear();
229  /// assert_eq!(bytes.len(), 0);
230  /// ```
231  #[cfg_attr(not(coverage), inline(always))]
232  pub fn clear(&mut self) {
233    match &mut self.0 {
234      Repr::Inline(b) => b.clear(),
235      Repr::Heap(b) => b.clear(),
236    }
237  }
238
239  /// Shortens the buffer, keeping the first len bytes and dropping the rest.
240  ///
241  /// If len is greater than the buffer’s current length, this has no effect.
242  ///
243  /// Existing underlying capacity is preserved.
244  ///
245  /// ## Example
246  ///
247  /// ```rust
248  /// use smol_bytes::BytesMut;
249  ///
250  /// let mut bytes = BytesMut::from(&b"hello world"[..]);
251  ///
252  /// bytes.truncate(5);
253  /// assert_eq!(bytes.as_slice(), b"hello");
254  /// ```
255  #[cfg_attr(not(coverage), inline(always))]
256  pub fn truncate(&mut self, len: usize) {
257    match &mut self.0 {
258      Repr::Inline(b) => b.truncate(len),
259      Repr::Heap(b) => b.truncate(len),
260    }
261  }
262
263  /// Returns the number of bytes the `BytesMut` can hold without reallocating.
264  ///
265  /// ## Example
266  ///
267  /// ```rust
268  ///
269  /// use smol_bytes::BytesMut;
270  ///
271  /// let bytes = BytesMut::with_capacity(100);
272  ///
273  /// assert_eq!(bytes.capacity(), 100);
274  /// ```
275  #[cfg_attr(not(coverage), inline(always))]
276  pub fn capacity(&self) -> usize {
277    match &self.0 {
278      Repr::Inline(b) => b.capacity(),
279      Repr::Heap(b) => b.capacity(),
280    }
281  }
282
283  /// Returns `true` if the `BytesMut` is using inline storage.
284  ///
285  /// ## Examples
286  ///
287  /// ```rust
288  /// use smol_bytes::BytesMut;
289  ///
290  /// let inline_buf = BytesMut::with_capacity(10);
291  /// assert!(inline_buf.is_inline());
292  ///
293  /// let heap_buf = BytesMut::with_capacity(100);
294  /// assert!(!heap_buf.is_inline());
295  /// ```
296  #[cfg_attr(not(coverage), inline(always))]
297  pub const fn is_inline(&self) -> bool {
298    matches!(&self.0, Repr::Inline(_))
299  }
300
301  /// Returns `true` if the `BytesMut` is using heap storage.
302  ///
303  /// ## Examples
304  ///
305  /// ```
306  /// use smol_bytes::BytesMut;
307  ///
308  /// let inline_buf = BytesMut::with_capacity(10);
309  /// assert!(!inline_buf.is_heap());
310  ///
311  /// let heap_buf = BytesMut::with_capacity(100);
312  /// assert!(heap_buf.is_heap());
313  /// ```
314  pub const fn is_heap(&self) -> bool {
315    matches!(&self.0, Repr::Heap(_))
316  }
317
318  /// Unwraps the inline buffer, consuming `self`.
319  ///
320  /// ## Panics
321  /// - Panics if the buffer is heap allocated.
322  ///
323  /// ## Examples
324  ///
325  /// ```
326  /// use smol_bytes::BytesMut;
327  ///
328  /// let buf = BytesMut::from(&b"hello"[..]);
329  ///
330  /// let inline_buffer = buf.unwrap_inline();
331  /// assert_eq!(&inline_buffer[..], b"hello");
332  /// ```
333  #[inline]
334  pub fn unwrap_inline(self) -> Buffer {
335    match self.0 {
336      Repr::Inline(b) => b,
337      Repr::Heap(_) => panic!("called `BytesMut::unwrap_inline()` on a heap allocated buffer"),
338    }
339  }
340
341  /// Attempts to unwrap the inline buffer, consuming `self`.
342  ///
343  /// ## Examples
344  ///
345  /// ```
346  /// use smol_bytes::BytesMut;
347  ///
348  /// let inline_buf = BytesMut::from(&b"hello"[..]);
349  /// let heap_buf = BytesMut::with_capacity(100);
350  ///
351  /// assert!(inline_buf.try_unwrap_inline().is_ok());
352  /// assert!(heap_buf.try_unwrap_inline().is_err());
353  /// ```
354  #[inline]
355  pub fn try_unwrap_inline(self) -> Result<Buffer, bytes::BytesMut> {
356    match self.0 {
357      Repr::Inline(b) => Ok(b),
358      Repr::Heap(b) => Err(b),
359    }
360  }
361
362  /// Unwraps the heap buffer, consuming `self`.
363  ///
364  /// ## Panics
365  /// - Panics if the buffer is inline.
366  ///
367  /// ## Examples
368  ///
369  /// ```
370  /// use smol_bytes::BytesMut;
371  ///
372  /// let mut buf = BytesMut::with_capacity(100);
373  /// buf.extend_from_slice(b"hello world and more data that exceeds inline capacity................................");
374  ///
375  /// let heap_buffer = buf.unwrap_heap();
376  /// assert_eq!(&heap_buffer[..], b"hello world and more data that exceeds inline capacity................................");
377  /// ```
378  #[inline]
379  pub fn unwrap_heap(self) -> bytes::BytesMut {
380    match self.0 {
381      Repr::Inline(_) => panic!("called `BytesMut::unwrap_heap()` on an inline buffer"),
382      Repr::Heap(b) => b,
383    }
384  }
385
386  /// Attempts to unwrap the heap buffer, consuming `self`.
387  ///
388  /// ## Examples
389  ///
390  /// ```
391  /// use smol_bytes::BytesMut;
392  ///
393  /// let inline_buf = BytesMut::from(&b"hello"[..]);
394  /// let mut heap_buf = BytesMut::with_capacity(100);
395  /// heap_buf.extend_from_slice(b"hello world and more data that exceeds inline capacity................................");
396  ///
397  /// assert!(heap_buf.try_unwrap_heap().is_ok());
398  /// assert!(inline_buf.try_unwrap_heap().is_err());
399  /// ```
400  #[inline]
401  pub fn try_unwrap_heap(self) -> Result<bytes::BytesMut, Buffer> {
402    match self.0 {
403      Repr::Inline(b) => Err(b),
404      Repr::Heap(b) => Ok(b),
405    }
406  }
407
408  /// Converts the `BytesMut` into a heap allocated buffer if it is currently inline.
409  ///
410  /// If the buffer is already heap allocated, this function does nothing.
411  ///
412  /// ## Examples
413  ///
414  /// ```
415  /// use smol_bytes::BytesMut;
416  ///
417  /// let mut buf = BytesMut::from(&b"hello"[..]);
418  /// assert!(buf.is_inline());
419  /// buf.make_heap();
420  /// assert!(buf.is_heap());
421  /// ```
422  pub fn make_heap(&mut self) {
423    match &mut self.0 {
424      Repr::Inline(b) => {
425        let mut new_buf = bytes::BytesMut::with_capacity(b.len());
426        new_buf.put_slice(b.as_slice());
427        self.0 = Repr::Heap(new_buf);
428      }
429      Repr::Heap(_) => {}
430    }
431  }
432
433  /// Splits the bytes into two at the given index.
434  ///
435  /// Afterwards `self` contains elements `[0, at)`, and the returned value
436  /// contains elements `[at, capacity)`. Any reserved-but-unwritten
437  /// capacity is partitioned between the two halves — this matches the
438  /// semantics of [`bytes::BytesMut::split_off`].
439  ///
440  /// For heap-allocated buffers, this is an `O(1)` operation that increases the
441  /// reference count and returns `Ok(BytesMut)`.
442  ///
443  /// For inline buffers where `at` lies within the written length, the
444  /// tail is copied into a `Buffer` and returned as `Err(Buffer)`.
445  /// For inline buffers where `at > len` (splitting into uninitialized
446  /// capacity), the buffer is first promoted to heap and the split returns
447  /// `Ok(BytesMut)`.
448  ///
449  /// ## Examples
450  ///
451  /// Splitting within written data on an inline buffer:
452  ///
453  /// ```
454  /// use smol_bytes::BytesMut;
455  ///
456  /// let mut a = BytesMut::from(&b"hello world"[..]);
457  /// match a.split_off(5) {
458  ///     Ok(mut b) => {
459  ///         // Heap: BytesMut can grow beyond 62 bytes
460  ///         b[0] = b'!';
461  ///         assert_eq!(&b[..], b"!world");
462  ///     }
463  ///     Err(mut b) => {
464  ///         // Inline: Buffer is limited to 62 bytes but still mutable
465  ///         assert_eq!(&b[..], b" world");
466  ///     }
467  /// }
468  /// assert_eq!(&a[..], b"hello");
469  /// ```
470  ///
471  /// Splitting into uninitialized capacity on a heap buffer:
472  ///
473  /// ```
474  /// use smol_bytes::BytesMut;
475  ///
476  /// let mut a = BytesMut::with_capacity(1024);
477  /// let b = a.split_off(128).unwrap();
478  /// assert_eq!(a.len(), 0);
479  /// assert_eq!(a.capacity(), 128);
480  /// assert_eq!(b.len(), 0);
481  /// assert_eq!(b.capacity(), 896);
482  /// ```
483  ///
484  /// ## Panics
485  ///
486  /// Panics if `at > capacity`.
487  #[must_use = "consider BytesMut::truncate if you don't need the other half"]
488  pub fn split_off(&mut self, at: usize) -> Result<Self, Buffer> {
489    self
490      .try_split_off(at)
491      .unwrap_or_else(|_| panic!("split_off out of bounds: {} > {}", at, self.capacity()))
492  }
493
494  /// Attempts to split the buffer at `at`.
495  ///
496  /// Returns [`OutOfBounds`] instead of panicking when `at > capacity`.
497  ///
498  /// See also [`split_off`](Self::split_off).
499  pub fn try_split_off(&mut self, at: usize) -> Result<Result<Self, Buffer>, OutOfBounds> {
500    let cap = self.capacity();
501    if at > cap {
502      return Err(OutOfBounds::new(at, cap));
503    }
504
505    // For inline buffers where `at` exceeds the written length, the `Buffer`
506    // type has no way to represent "reserved but unwritten" capacity, so we
507    // promote to heap before splitting.
508    if let Repr::Inline(b) = &self.0 {
509      if at > b.remaining() {
510        let mut new_heap = bytes::BytesMut::with_capacity(cap);
511        new_heap.extend_from_slice(b.as_slice());
512        self.0 = Repr::Heap(new_heap);
513      }
514    }
515
516    let result = match &mut self.0 {
517      Repr::Inline(b) => Err(b.try_split_off(at).expect("validated bounds")),
518      Repr::Heap(b) => Ok(Self(Repr::Heap(b.split_off(at)))),
519    };
520    Ok(result)
521  }
522
523  /// Removes the bytes from the current view, returning them in a new buffer.
524  ///
525  /// Afterwards, `self` will be empty, but will retain any additional
526  /// capacity that it had before the operation. This is identical to
527  /// `self.split_to(self.len())`.
528  ///
529  /// For heap buffers, this is an `O(1)` operation.
530  /// For inline buffers, the data is copied into a `Buffer`.
531  ///
532  /// ## Examples
533  ///
534  /// ```
535  /// use smol_bytes::{BytesMut, BufMut};
536  ///
537  /// let mut buf = BytesMut::with_capacity(1024);
538  /// buf.put(&b"hello world"[..]);
539  /// let other = buf.split().unwrap();
540  /// assert!(buf.is_empty());
541  /// assert_eq!(other, b"hello world"[..]);
542  /// ```
543  #[must_use = "consider BytesMut::clear if you don't need the other half"]
544  pub fn split(&mut self) -> Result<Self, Buffer> {
545    let len = self.len();
546    self
547      .try_split_to(len)
548      .unwrap_or_else(|_| panic!("split out of bounds: {}", len))
549  }
550
551  /// Splits the buffer into two at the given index.
552  ///
553  /// Afterwards `self` contains elements `[at, len)`, and the returned value
554  /// contains elements `[0, at)`.
555  ///
556  /// For heap-allocated buffers, this is an `O(1)` operation that increases the
557  /// reference count and returns `Ok(BytesMut)`.
558  ///
559  /// For inline buffers, the head is copied into a `Buffer` and returned as `Err(Buffer)`.
560  /// Both `BytesMut` and `Buffer` are mutable, but `Buffer` is limited to 62 bytes inline storage.
561  ///
562  /// ## Examples
563  ///
564  /// ```
565  /// use smol_bytes::BytesMut;
566  ///
567  /// // Inline buffer
568  /// let mut a = BytesMut::from(&b"hello world"[..]);
569  /// match a.split_to(5) {
570  ///     Ok(mut b) => {
571  ///         // Heap: BytesMut can grow beyond 62 bytes
572  ///         b[0] = b'j';
573  ///         assert_eq!(&b[..], b"jello");
574  ///     }
575  ///     Err(b) => {
576  ///         // Inline: Buffer is limited to 62 bytes but still mutable
577  ///         assert_eq!(&b[..], b"hello");
578  ///     }
579  /// }
580  /// assert_eq!(&a[..], b" world");
581  ///
582  /// // Heap buffer
583  /// let mut a = BytesMut::with_capacity(64);
584  /// a.extend_from_slice(b"hello world");
585  /// let mut b = a.split_to(5).unwrap();
586  /// a[0] = b'!';  // Replaces the space with '!'
587  /// b[0] = b'j';
588  /// assert_eq!(&a[..], b"!world");
589  /// assert_eq!(&b[..], b"jello");
590  /// ```
591  ///
592  /// ## Panics
593  ///
594  /// Panics if `at > len`.
595  #[must_use = "consider BytesMut::advance if you don't need the other half"]
596  pub fn split_to(&mut self, at: usize) -> Result<Self, Buffer> {
597    self
598      .try_split_to(at)
599      .unwrap_or_else(|_| panic!("split_to out of bounds: {} > {}", at, self.len()))
600  }
601
602  /// Attempts to split at `at`, returning [`OutOfBounds`] on failure instead of panicking.
603  ///
604  /// See also [`split_to`](Self::split_to).
605  pub fn try_split_to(&mut self, at: usize) -> Result<Result<Self, Buffer>, OutOfBounds> {
606    let len = self.len();
607    if at > len {
608      return Err(OutOfBounds::new(at, len));
609    }
610
611    let result = match &mut self.0 {
612      Repr::Inline(b) => Err(b.try_split_to(at).expect("validated bounds")),
613      Repr::Heap(b) => Ok(Self(Repr::Heap(b.split_to(at)))),
614    };
615    Ok(result)
616  }
617
618  /// Attempts to split off all remaining bytes.
619  ///
620  /// See also [`split`](Self::split).
621  pub fn try_split(&mut self) -> Result<Result<Self, Buffer>, OutOfBounds> {
622    let len = self.len();
623    self.try_split_to(len)
624  }
625
626  /// Attempts to advance the readable cursor by `cnt` bytes.
627  pub fn try_advance(&mut self, cnt: usize) -> Result<(), OutOfBounds> {
628    let len = self.len();
629    if cnt > len {
630      return Err(OutOfBounds::new(cnt, len));
631    }
632
633    match &mut self.0 {
634      Repr::Inline(buffer) => buffer.try_advance(cnt),
635      Repr::Heap(bytes) => {
636        Buf::advance(bytes, cnt);
637        Ok(())
638      }
639    }
640  }
641
642  /// Attempts to write an unsigned n-byte integer in big-endian byte order.
643  pub fn try_put_uint(&mut self, n: u64, nbytes: usize) -> Result<(), InvalidIntegerLength> {
644    if nbytes > 8 {
645      return Err(InvalidIntegerLength(nbytes));
646    }
647
648    self.put_uint(n, nbytes);
649    Ok(())
650  }
651
652  /// Attempts to write an unsigned n-byte integer in little-endian byte order.
653  pub fn try_put_uint_le(&mut self, n: u64, nbytes: usize) -> Result<(), InvalidIntegerLength> {
654    if nbytes > 8 {
655      return Err(InvalidIntegerLength(nbytes));
656    }
657    self.put_uint_le(n, nbytes);
658    Ok(())
659  }
660
661  /// Attempts to write a signed n-byte integer in big-endian byte order.
662  pub fn try_put_int(&mut self, n: i64, nbytes: usize) -> Result<(), InvalidIntegerLength> {
663    if nbytes > 8 {
664      return Err(InvalidIntegerLength(nbytes));
665    }
666    self.put_int(n, nbytes);
667    Ok(())
668  }
669
670  /// Attempts to write a signed n-byte integer in little-endian byte order.
671  pub fn try_put_int_le(&mut self, n: i64, nbytes: usize) -> Result<(), InvalidIntegerLength> {
672    if nbytes > 8 {
673      return Err(InvalidIntegerLength(nbytes));
674    }
675    self.put_int_le(n, nbytes);
676    Ok(())
677  }
678
679  /// Attempts to write an unsigned n-byte integer in native-endian byte order
680  pub fn try_put_uint_ne(&mut self, n: u64, nbytes: usize) -> Result<(), InvalidIntegerLength> {
681    if nbytes > 8 {
682      return Err(InvalidIntegerLength(nbytes));
683    }
684    self.put_uint_ne(n, nbytes);
685    Ok(())
686  }
687
688  /// Attempts to write a signed n-byte integer in native-endian byte order
689  pub fn try_put_int_ne(&mut self, n: i64, nbytes: usize) -> Result<(), InvalidIntegerLength> {
690    if nbytes > 8 {
691      return Err(InvalidIntegerLength(nbytes));
692    }
693    self.put_int_ne(n, nbytes);
694    Ok(())
695  }
696
697  /// Absorbs a `BytesMut` that was previously split off.
698  ///
699  /// Both `BytesMut` objects must be heap allocated for this to succeed. If one of them
700  /// is inline, the method returns `Some(other)`, leaving `self` unchanged.
701  ///
702  /// If the two `BytesMut` objects were previously contiguous and not mutated
703  /// in a way that causes re-allocation i.e., if `other` was created by
704  /// calling `split_off` on this `BytesMut`, then this is an `O(1)` operation
705  /// that just decreases a reference count and sets a few indices.
706  /// Otherwise this method degenerates to
707  /// `self.extend_from_slice(other.as_ref())`.
708  ///
709  /// ## Examples
710  ///
711  /// ```
712  /// use smol_bytes::BytesMut;
713  ///
714  /// let mut buf = BytesMut::with_capacity(64);
715  /// buf.extend_from_slice(b"aaabbbcccddd");
716  ///
717  /// let split = buf.split_off(6).unwrap();
718  /// assert_eq!(b"aaabbb", &buf[..]);
719  /// assert_eq!(b"cccddd", &split[..]);
720  ///
721  /// assert!(buf.unsplit(split).is_none());
722  /// assert_eq!(b"aaabbbcccddd", &buf[..]);
723  /// ```
724  pub fn unsplit(&mut self, other: Self) -> Option<Self> {
725    match (&mut self.0, other.0) {
726      (Repr::Heap(b1), Repr::Heap(b2)) => {
727        b1.unsplit(b2);
728        None
729      }
730      (_, Repr::Inline(storage)) => Some(Self(Repr::Inline(storage))),
731      (_, Repr::Heap(bytes_mut)) => Some(Self(Repr::Heap(bytes_mut))),
732    }
733  }
734
735  #[inline]
736  pub(crate) fn freeze<S>(self) -> RawBytes<S>
737  where
738    RawBytes<S>: crate::strategy::ImmutableStorage,
739  {
740    match self.0 {
741      Repr::Inline(storage) => RawBytes::inline(storage),
742      Repr::Heap(b) => RawBytes::heap(b.freeze()),
743    }
744  }
745
746  /// Converts `self` into an immutable [`shared::Bytes`](crate::shared::Bytes).
747  ///
748  /// The conversion is zero cost and is used to indicate that the slice
749  /// referenced by the handle will no longer be mutated. Once the conversion
750  /// is done, the handle can be cloned and shared across threads.
751  ///
752  /// ## Examples
753  ///
754  /// ```
755  /// use smol_bytes::{BytesMut, BufMut};
756  /// use std::thread;
757  ///
758  /// let mut b = BytesMut::with_capacity(64);
759  /// b.put(&b"hello world"[..]);
760  /// let b1 = b.freeze_shared();
761  /// let b2 = b1.clone();
762  ///
763  /// let th = thread::spawn(move || {
764  ///     assert_eq!(&b1[..], b"hello world");
765  /// });
766  ///
767  /// assert_eq!(&b2[..], b"hello world");
768  /// th.join().unwrap();
769  /// ```
770  pub fn freeze_shared(self) -> crate::shared::Bytes {
771    self.freeze()
772  }
773
774  /// Converts `self` into an immutable [`compact::Bytes`](crate::compact::Bytes).
775  ///
776  /// The conversion is zero cost and is used to indicate that the slice
777  /// referenced by the handle will no longer be mutated. Once the conversion
778  /// is done, the handle can be cloned and shared across threads.
779  ///
780  /// ## Examples
781  ///
782  /// ```
783  /// use smol_bytes::{BytesMut, BufMut};
784  /// use std::thread;
785  ///
786  /// let mut b = BytesMut::with_capacity(64);
787  /// b.put(&b"hello world"[..]);
788  /// let b1 = b.freeze_compact();
789  /// let b2 = b1.clone();
790  ///
791  /// let th = thread::spawn(move || {
792  ///     assert_eq!(&b1[..], b"hello world");
793  /// });
794  ///
795  /// assert_eq!(&b2[..], b"hello world");
796  /// th.join().unwrap();
797  /// ```
798  pub fn freeze_compact(self) -> crate::compact::Bytes {
799    self.freeze()
800  }
801
802  /// Returns the remaining spare capacity of the buffer as a slice of [`MaybeUninit<u8>`].
803  ///
804  /// The returned slice can be used to fill the buffer with data (e.g. by reading from a file) before marking the data as initialized using the [`set_len`](Self::set_len) method.
805  ///
806  /// ## Example
807  ///
808  /// ```
809  /// use smol_bytes::{BytesMut, INLINE_CAP};
810  ///
811  /// // Allocate buffer big enough for 10 bytes.
812  /// let mut buf = BytesMut::with_capacity(10);
813  ///
814  /// // Fill in the first 3 elements.
815  /// let uninit = buf.spare_capacity_mut();
816  /// uninit[0].write(0);
817  /// uninit[1].write(1);
818  /// uninit[2].write(2);
819  ///
820  /// // Mark the first 3 bytes of the buffer as being initialized.
821  /// unsafe {
822  ///   buf.set_len(3);
823  /// }
824  ///
825  /// assert_eq!(&buf[..], &[0, 1, 2]);
826  /// ```
827  pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
828    match &mut self.0 {
829      Repr::Inline(b) => b.spare_capacity_mut(),
830      Repr::Heap(b) => b.spare_capacity_mut(),
831    }
832  }
833
834  /// Attempts to cheaply reclaim already allocated capacity for at least `additional` more
835  /// bytes to be inserted into the given `BytesMut` and returns `true` if it succeeded.
836  ///
837  /// `try_reclaim` behaves exactly like `reserve`, except that it never allocates new storage
838  /// and returns a `bool` indicating whether it was successful in doing so:
839  ///
840  /// `try_reclaim` returns false under these conditions:
841  ///  - The spare capacity left is less than `additional` bytes AND
842  ///  - The existing allocation cannot be reclaimed cheaply or it was less than
843  ///    `additional` bytes in size
844  ///
845  /// Reclaiming the allocation cheaply is possible if the `BytesMut` has no outstanding
846  /// references through other `BytesMut`s or `Bytes` which point to the same underlying
847  /// storage.
848  ///
849  /// ## Examples
850  ///
851  /// ```
852  /// use smol_bytes::BytesMut;
853  ///
854  /// let mut buf = BytesMut::with_capacity(64);
855  /// assert_eq!(true, buf.try_reclaim(64));
856  /// assert_eq!(64, buf.capacity());
857  ///
858  /// buf.extend_from_slice(b"abcd");
859  /// let mut split = buf.split().unwrap();
860  /// assert_eq!(60, buf.capacity());
861  /// assert_eq!(4, split.len());
862  /// assert_eq!(false, split.try_reclaim(64));
863  /// assert_eq!(false, buf.try_reclaim(64));
864  /// // The split buffer is filled with "abcd"
865  /// assert_eq!(false, split.try_reclaim(4));
866  /// // buf is empty and has capacity for 60 bytes
867  /// assert_eq!(true, buf.try_reclaim(60));
868  ///
869  /// drop(buf);
870  /// assert_eq!(false, split.try_reclaim(64));
871  ///
872  /// split.clear();
873  /// assert_eq!(4, split.capacity());
874  /// assert_eq!(true, split.try_reclaim(64));
875  /// assert_eq!(64, split.capacity());
876  /// ```
877  #[inline]
878  #[must_use = "consider BytesMut::reserve if you need an infallible reservation"]
879  pub fn try_reclaim(&mut self, additional: usize) -> bool {
880    match &mut self.0 {
881      Repr::Inline(b) => b.try_reclaim(additional),
882      Repr::Heap(b) => b.try_reclaim(additional),
883    }
884  }
885
886  /// Sets the visible length of the buffer.
887  ///
888  /// This will explicitly set the size of the buffer without actually
889  /// modifying the data, so it is up to the caller to ensure that the data
890  /// has been initialized.
891  ///
892  /// ## Safety
893  ///
894  /// - `len` must not exceed [`capacity`](Self::capacity).
895  /// - Every byte in the current view's `0..len` range must be initialized.
896  ///
897  /// ## Examples
898  ///
899  /// ```
900  /// use smol_bytes::BytesMut;
901  ///
902  /// let mut b = BytesMut::from(&b"hello world"[..]);
903  ///
904  /// unsafe {
905  ///     b.set_len(5);
906  /// }
907  ///
908  /// assert_eq!(&b[..], b"hello");
909  ///
910  /// unsafe {
911  ///     b.set_len(11);
912  /// }
913  ///
914  /// assert_eq!(&b[..], b"hello world");
915  /// ```
916  #[allow(clippy::missing_safety_doc)]
917  #[inline]
918  pub unsafe fn set_len(&mut self, len: usize) {
919    // SAFETY: both inner methods interpret `len` as a visible length. The
920    // caller guarantees `len <= capacity()` and that every byte newly exposed
921    // in the current view is initialized.
922    unsafe {
923      match &mut self.0 {
924        Repr::Inline(b) => b.set_len(len),
925        Repr::Heap(b) => b.set_len(len),
926      }
927    }
928  }
929
930  /// Resizes the buffer so that `len` is equal to `new_len`.
931  ///
932  /// If `new_len` is greater than `len`, the buffer is extended by the
933  /// difference with each additional byte set to `value`. If `new_len` is
934  /// less than `len`, the buffer is simply truncated.
935  ///
936  /// ## Examples
937  ///
938  /// ```
939  /// use smol_bytes::BytesMut;
940  ///
941  /// let mut buf = BytesMut::new();
942  ///
943  /// buf.resize(3, 0x1);
944  /// assert_eq!(&buf[..], &[0x1, 0x1, 0x1]);
945  ///
946  /// buf.resize(2, 0x2);
947  /// assert_eq!(&buf[..], &[0x1, 0x1]);
948  ///
949  /// buf.resize(4, 0x3);
950  /// assert_eq!(&buf[..], &[0x1, 0x1, 0x3, 0x3]);
951  /// ```
952  pub fn resize(&mut self, new_len: usize, value: u8) {
953    let current_len = self.len();
954    if new_len < current_len {
955      self.truncate(new_len);
956      return;
957    }
958
959    let additional = new_len - current_len;
960    if additional == 0 {
961      return;
962    }
963
964    self.reserve(additional);
965    match &mut self.0 {
966      Repr::Inline(storage) => storage.put_bytes(value, additional),
967      Repr::Heap(b) => b.resize(new_len, value),
968    }
969  }
970
971  /// Reserves capacity for at least `additional` more bytes to be inserted
972  /// into the given `BytesMut`.
973  ///
974  /// More than `additional` bytes may be reserved in order to avoid frequent
975  /// reallocations. A call to `reserve` may result in an allocation.
976  ///
977  /// Before allocating new buffer space, the function will attempt to reclaim
978  /// space in the existing buffer. If the current handle references a view
979  /// into a larger original buffer, and all other handles referencing part
980  /// of the same original buffer have been dropped, then the current view
981  /// can be copied/shifted to the front of the buffer and the handle can take
982  /// ownership of the full buffer, provided that the full buffer is large
983  /// enough to fit the requested additional capacity.
984  ///
985  /// This optimization will only happen if shifting the data from the current
986  /// view to the front of the buffer is not too expensive in terms of the
987  /// (amortized) time required. The precise condition is subject to change;
988  /// as of now, the length of the data being shifted needs to be at least as
989  /// large as the distance that it's shifted by. If the current view is empty
990  /// and the original buffer is large enough to fit the requested additional
991  /// capacity, then reallocations will never happen.
992  ///
993  /// ## Examples
994  ///
995  /// In the following example, a new buffer is allocated.
996  ///
997  /// ```
998  /// use smol_bytes::BytesMut;
999  ///
1000  /// let mut buf = BytesMut::from(&b"hello"[..]);
1001  /// buf.reserve(64);
1002  /// assert!(buf.capacity() >= 69);
1003  /// ```
1004  ///
1005  /// ## Panics
1006  ///
1007  /// Panics if the new capacity overflows `usize`.
1008  #[inline]
1009  pub fn reserve(&mut self, additional: usize) {
1010    let required = self
1011      .len()
1012      .checked_add(additional)
1013      .expect("capacity overflow");
1014
1015    match &mut self.0 {
1016      Repr::Inline(storage) => {
1017        if storage.try_reclaim(additional) {
1018          return;
1019        }
1020
1021        let mut new_buf = bytes::BytesMut::with_capacity(required);
1022        new_buf.extend_from_slice(storage.as_slice());
1023        self.0 = Repr::Heap(new_buf);
1024      }
1025      Repr::Heap(b) => b.reserve(additional),
1026    }
1027  }
1028
1029  /// Returns the number of bytes contained in this `BytesMut`.
1030  ///
1031  /// ## Example
1032  ///
1033  /// ```rust
1034  /// use smol_bytes::BytesMut;
1035  ///
1036  /// let bytes = BytesMut::new();
1037  /// assert_eq!(bytes.len(), 0);
1038  /// ```
1039  #[cfg_attr(not(coverage), inline(always))]
1040  pub fn len(&self) -> usize {
1041    match &self.0 {
1042      Repr::Inline(b) => b.len(),
1043      Repr::Heap(b) => b.len(),
1044    }
1045  }
1046
1047  /// Returns `true` if the BytesMut has a length of `0`.
1048  ///
1049  /// ## Example
1050  ///
1051  /// ```rust
1052  /// use smol_bytes::BytesMut;
1053  ///
1054  /// let bytes = BytesMut::new();
1055  /// assert!(bytes.is_empty());
1056  /// ```
1057  #[cfg_attr(not(coverage), inline(always))]
1058  pub fn is_empty(&self) -> bool {
1059    self.len() == 0
1060  }
1061
1062  /// Returns a slice of the buffer's contents.
1063  ///
1064  /// ## Example
1065  ///
1066  /// ```rust
1067  /// use smol_bytes::BytesMut;
1068  ///
1069  /// let buf = BytesMut::from(&b"hello"[..]);
1070  /// assert_eq!(buf.as_slice(), b"hello");
1071  /// ```
1072  #[cfg_attr(not(coverage), inline(always))]
1073  pub fn as_slice(&self) -> &[u8] {
1074    self
1075  }
1076
1077  /// Returns a mutable slice of the buffer's contents.
1078  ///
1079  /// ## Example
1080  ///
1081  /// ```rust
1082  /// use smol_bytes::BytesMut;
1083  ///
1084  /// let mut buf = BytesMut::from(&b"hello"[..]);
1085  /// buf.as_mut_slice()[0] = b'j';
1086  /// assert_eq!(buf.as_slice(), b"jello");
1087  /// ```
1088  #[cfg_attr(not(coverage), inline(always))]
1089  pub fn as_mut_slice(&mut self) -> &mut [u8] {
1090    self
1091  }
1092}
1093
1094impl Buf for BytesMut {
1095  #[cfg_attr(not(coverage), inline(always))]
1096  fn remaining(&self) -> usize {
1097    match &self.0 {
1098      Repr::Inline(b) => b.remaining(),
1099      Repr::Heap(b) => b.remaining(),
1100    }
1101  }
1102
1103  #[cfg_attr(not(coverage), inline(always))]
1104  fn chunk(&self) -> &[u8] {
1105    match &self.0 {
1106      Repr::Inline(b) => b.as_slice(),
1107      Repr::Heap(b) => b.chunk(),
1108    }
1109  }
1110
1111  #[cfg_attr(not(coverage), inline(always))]
1112  fn advance(&mut self, cnt: usize) {
1113    match &mut self.0 {
1114      Repr::Inline(b) => b.advance(cnt),
1115      Repr::Heap(b) => b.advance(cnt),
1116    }
1117  }
1118
1119  #[cfg_attr(not(coverage), inline(always))]
1120  fn copy_to_bytes(&mut self, len: usize) -> bytes::Bytes {
1121    match self.split_to(len) {
1122      Ok(a) => a.freeze_shared().into(),
1123      Err(b) => ::bytes::Bytes::copy_from_slice(b.as_slice()),
1124    }
1125  }
1126
1127  crate::macros::forward_buf! { 0 {
1128    i16,
1129    i32,
1130    i64,
1131    i128,
1132    u16,
1133    u32,
1134    u64,
1135    u128,
1136    f32,
1137    f64,
1138  }}
1139}
1140
1141unsafe impl BufMut for BytesMut {
1142  #[cfg_attr(not(coverage), inline(always))]
1143  fn remaining_mut(&self) -> usize {
1144    usize::MAX - self.len()
1145  }
1146
1147  unsafe fn advance_mut(&mut self, cnt: usize) {
1148    // SAFETY: forwards to the inner buffer's `advance_mut`; the caller's
1149    // safety contract applies identically to the inner representation.
1150    unsafe {
1151      match &mut self.0 {
1152        Repr::Inline(b) => b.advance_mut(cnt),
1153        Repr::Heap(b) => b.advance_mut(cnt),
1154      }
1155    }
1156  }
1157
1158  fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
1159    let promote = match &mut self.0 {
1160      Repr::Inline(buffer) if buffer.remaining_mut() == 0 => !buffer.try_reclaim(1),
1161      _ => false,
1162    };
1163
1164    if promote {
1165      self.reserve(64);
1166    }
1167
1168    match &mut self.0 {
1169      Repr::Inline(b) => b.chunk_mut(),
1170      Repr::Heap(b) => b.chunk_mut(),
1171    }
1172  }
1173
1174  fn put_slice(&mut self, src: &[u8]) {
1175    self.extend_from_slice(src);
1176  }
1177
1178  fn put_bytes(&mut self, val: u8, cnt: usize) {
1179    self.reserve(cnt);
1180
1181    match &mut self.0 {
1182      Repr::Inline(b) => b.put_bytes(val, cnt),
1183      Repr::Heap(b) => b.put_bytes(val, cnt),
1184    }
1185  }
1186}
1187
1188#[derive(Clone)]
1189enum Repr {
1190  Inline(Buffer),
1191  Heap(bytes::BytesMut),
1192}