ntex_bytes/buf/buf_mut.rs
1use std::{cmp, mem};
2
3use super::UninitSlice;
4
5/// Generates the fixed-width integer `put_*` methods of `BufMut`, with docs.
6macro_rules! put_int_impl {
7 ($($name:ident, $ty:ty, $conv:ident, $what:literal, $order:literal, $size:literal, $val:literal, $bytes:literal;)*) => {$(
8 #[doc = concat!("Writes ", $what, " to `self` in ", $order, " byte order.")]
9 ///
10 #[doc = concat!("The current position is advanced by ", $size, ".")]
11 ///
12 /// # Examples
13 ///
14 /// ```
15 /// use ntex_bytes::BufMut;
16 ///
17 /// let mut buf = vec![];
18 #[doc = concat!("buf.", stringify!($name), "(", $val, ");")]
19 #[doc = concat!("assert_eq!(buf, b\"", $bytes, "\");")]
20 /// ```
21 ///
22 /// # Panics
23 ///
24 /// This function panics if there is not enough remaining capacity in
25 /// `self`.
26 #[inline]
27 fn $name(&mut self, n: $ty) {
28 self.put_slice(&n.$conv());
29 }
30 )*};
31}
32/// A trait for values that provide sequential write access to bytes.
33///
34/// A buffer stores bytes in memory such that write operations are infallible.
35/// The underlying storage may or may not be in contiguous memory. A `BufMut`
36/// value is a cursor into the buffer. Writing to `BufMut` advances the cursor
37/// position.
38///
39/// Fixed-size buffers such as `&mut [u8]` panic when a write does not fit.
40/// Growable buffers such as `Vec<u8>`, [`BytesMut`](crate::BytesMut) and
41/// [`BytePages`](crate::BytePages) allocate more space on demand instead, so
42/// the `put_*` methods never run out of capacity for them.
43///
44/// The simplest `BufMut` is a `Vec<u8>`.
45///
46/// ```
47/// use ntex_bytes::BufMut;
48///
49/// let mut buf = vec![];
50///
51/// buf.put_slice(b"hello world");
52///
53/// assert_eq!(buf, b"hello world");
54/// ```
55pub trait BufMut {
56 /// Returns the number of bytes that can be written from the current
57 /// position until the end of the buffer is reached.
58 ///
59 /// This value is greater than or equal to the length of the slice returned
60 /// by `chunk_mut`.
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// use ntex_bytes::BufMut;
66 ///
67 /// let mut dst = [0; 10];
68 /// let mut buf = &mut dst[..];
69 ///
70 /// let original_remaining = buf.remaining_mut();
71 /// buf.put_slice(b"hello");
72 ///
73 /// assert_eq!(original_remaining - 5, buf.remaining_mut());
74 /// ```
75 ///
76 /// # Implementer notes
77 ///
78 /// Implementations of `remaining_mut` should ensure that the return value
79 /// does not change unless a call is made to `advance_mut` or any other
80 /// function that is documented to change the `BufMut`'s current position.
81 fn remaining_mut(&self) -> usize;
82
83 /// Advance the internal cursor of the `BufMut`
84 ///
85 /// The next call to `chunk_mut` will return a slice starting `cnt` bytes
86 /// further into the underlying buffer.
87 ///
88 /// # Safety
89 ///
90 /// The caller must ensure that the `cnt` bytes being advanced past have
91 /// been initialized.
92 ///
93 /// # Examples
94 ///
95 /// ```
96 /// use ntex_bytes::BufMut;
97 ///
98 /// let mut buf = Vec::with_capacity(16);
99 ///
100 /// unsafe {
101 /// buf.chunk_mut()[0..2].copy_from_slice(b"he");
102 /// buf.advance_mut(2);
103 ///
104 /// buf.chunk_mut()[0..3].copy_from_slice(b"llo");
105 /// buf.advance_mut(3);
106 /// }
107 ///
108 /// assert_eq!(5, buf.len());
109 /// assert_eq!(buf, b"hello");
110 /// ```
111 ///
112 /// # Panics
113 ///
114 /// This function **may** panic if `cnt > self.remaining_mut()`.
115 ///
116 /// # Implementer notes
117 ///
118 /// It is recommended for implementations of `advance_mut` to panic if
119 /// `cnt > self.remaining_mut()`. If the implementation does not panic,
120 /// the call must behave as if `cnt == self.remaining_mut()`.
121 ///
122 /// A call with `cnt == 0` should never panic and be a no-op.
123 unsafe fn advance_mut(&mut self, cnt: usize);
124
125 /// Returns true if there is space in `self` for more bytes.
126 ///
127 /// This is equivalent to `self.remaining_mut() != 0`.
128 ///
129 /// # Examples
130 ///
131 /// ```
132 /// use ntex_bytes::BufMut;
133 ///
134 /// let mut dst = [0; 5];
135 /// let mut buf = &mut dst[..];
136 ///
137 /// assert!(buf.has_remaining_mut());
138 ///
139 /// buf.put_slice(b"hello");
140 ///
141 /// assert!(!buf.has_remaining_mut());
142 /// ```
143 #[inline]
144 fn has_remaining_mut(&self) -> bool {
145 self.remaining_mut() > 0
146 }
147
148 /// Returns a mutable slice starting at the current `BufMut` position and of
149 /// length between 0 and `BufMut::remaining_mut()`. Note that this *can* be shorter than the
150 /// whole remainder of the buffer (this allows non-continuous implementation).
151 ///
152 /// This is a lower level function. Most operations are done with other
153 /// functions.
154 ///
155 /// The returned byte slice may represent uninitialized memory.
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// use ntex_bytes::BufMut;
161 ///
162 /// let mut buf = Vec::with_capacity(16);
163 ///
164 /// unsafe {
165 /// buf.chunk_mut()[0..2].copy_from_slice(b"he");
166 ///
167 /// buf.advance_mut(2);
168 ///
169 /// buf.chunk_mut()[0..3].copy_from_slice(b"llo");
170 ///
171 /// buf.advance_mut(3);
172 /// }
173 ///
174 /// assert_eq!(5, buf.len());
175 /// assert_eq!(buf, b"hello");
176 /// ```
177 ///
178 /// # Implementer notes
179 ///
180 /// This function should never panic. `chunk_mut` should return an empty
181 /// slice **if and only if** `remaining_mut` returns 0. In other words,
182 /// `chunk_mut` returning an empty slice implies that `remaining_mut` will
183 /// return 0 and `remaining_mut` returning 0 implies that `chunk_mut` will
184 /// return an empty slice.
185 fn chunk_mut(&mut self) -> &mut UninitSlice;
186
187 /// Transfer bytes into `self` from `src` and advance the cursor by the
188 /// number of bytes written.
189 ///
190 /// # Examples
191 ///
192 /// ```
193 /// use ntex_bytes::BufMut;
194 ///
195 /// let mut buf = vec![];
196 ///
197 /// buf.put_u8(b'h');
198 /// buf.put(&b"ello"[..]);
199 /// buf.put_slice(b" world");
200 ///
201 /// assert_eq!(buf, b"hello world");
202 /// ```
203 ///
204 /// # Panics
205 ///
206 /// Panics if `self` does not have enough capacity to contain `src`.
207 fn put<T: super::Buf>(&mut self, mut src: T)
208 where
209 Self: Sized,
210 {
211 while src.has_remaining() {
212 let s = src.chunk();
213 let l = s.len();
214 self.put_slice(s);
215 src.advance(l);
216 }
217 }
218
219 /// Transfer bytes into `self` from `src` and advance the cursor by the
220 /// number of bytes written.
221 ///
222 /// `self` must have enough remaining capacity to contain all of `src`.
223 ///
224 /// ```
225 /// use ntex_bytes::BufMut;
226 ///
227 /// let mut dst = [0; 6];
228 ///
229 /// {
230 /// let mut buf = &mut dst[..];
231 /// buf.put_slice(b"hello");
232 ///
233 /// assert_eq!(1, buf.remaining_mut());
234 /// }
235 ///
236 /// assert_eq!(b"hello\0", &dst);
237 /// ```
238 fn put_slice(&mut self, src: &[u8]) {
239 let mut off = 0;
240
241 assert!(self.remaining_mut() >= src.len(), "buffer overflow");
242
243 while off < src.len() {
244 let dst = self.chunk_mut();
245 let cnt = cmp::min(dst.len(), src.len() - off);
246 dst[..cnt].copy_from_slice(&src[off..off + cnt]);
247 off += cnt;
248
249 // SAFETY: The `cnt` bytes in the writable chunk were initialized by the copy above.
250 unsafe {
251 self.advance_mut(cnt);
252 }
253 }
254 }
255
256 /// Writes an unsigned 8 bit integer to `self`.
257 ///
258 /// The current position is advanced by 1.
259 ///
260 /// # Examples
261 ///
262 /// ```
263 /// use ntex_bytes::BufMut;
264 ///
265 /// let mut buf = vec![];
266 /// buf.put_u8(0x01);
267 /// assert_eq!(buf, b"\x01");
268 /// ```
269 ///
270 /// # Panics
271 ///
272 /// This function panics if there is not enough remaining capacity in
273 /// `self`.
274 #[inline]
275 fn put_u8(&mut self, n: u8) {
276 let src = [n];
277 self.put_slice(&src);
278 }
279
280 /// Writes a signed 8 bit integer to `self`.
281 ///
282 /// The current position is advanced by 1.
283 ///
284 /// # Examples
285 ///
286 /// ```
287 /// use ntex_bytes::BufMut;
288 ///
289 /// let mut buf = vec![];
290 /// buf.put_i8(0x01);
291 /// assert_eq!(buf, b"\x01");
292 /// ```
293 ///
294 /// # Panics
295 ///
296 /// This function panics if there is not enough remaining capacity in
297 /// `self`.
298 fn put_i8(&mut self, n: i8) {
299 self.put_slice(&[n as u8]);
300 }
301
302 put_int_impl! {
303 put_u16, u16, to_be_bytes, "an unsigned 16 bit integer", "big-endian", 2, "0x0809", r"\x08\x09";
304 put_u16_le, u16, to_le_bytes, "an unsigned 16 bit integer", "little-endian", 2, "0x0809", r"\x09\x08";
305 put_i16, i16, to_be_bytes, "a signed 16 bit integer", "big-endian", 2, "0x0809", r"\x08\x09";
306 put_i16_le, i16, to_le_bytes, "a signed 16 bit integer", "little-endian", 2, "0x0809", r"\x09\x08";
307 put_u32, u32, to_be_bytes, "an unsigned 32 bit integer", "big-endian", 4, "0x0809A0A1", r"\x08\x09\xA0\xA1";
308 put_u32_le, u32, to_le_bytes, "an unsigned 32 bit integer", "little-endian", 4, "0x0809A0A1", r"\xA1\xA0\x09\x08";
309 put_i32, i32, to_be_bytes, "a signed 32 bit integer", "big-endian", 4, "0x0809A0A1", r"\x08\x09\xA0\xA1";
310 put_i32_le, i32, to_le_bytes, "a signed 32 bit integer", "little-endian", 4, "0x0809A0A1", r"\xA1\xA0\x09\x08";
311 put_u64, u64, to_be_bytes, "an unsigned 64 bit integer", "big-endian", 8, "0x0102030405060708", r"\x01\x02\x03\x04\x05\x06\x07\x08";
312 put_u64_le, u64, to_le_bytes, "an unsigned 64 bit integer", "little-endian", 8, "0x0102030405060708", r"\x08\x07\x06\x05\x04\x03\x02\x01";
313 put_i64, i64, to_be_bytes, "a signed 64 bit integer", "big-endian", 8, "0x0102030405060708", r"\x01\x02\x03\x04\x05\x06\x07\x08";
314 put_i64_le, i64, to_le_bytes, "a signed 64 bit integer", "little-endian", 8, "0x0102030405060708", r"\x08\x07\x06\x05\x04\x03\x02\x01";
315 put_u128, u128, to_be_bytes, "an unsigned 128 bit integer", "big-endian", 16, "0x01020304050607080910111213141516", r"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16";
316 put_u128_le, u128, to_le_bytes, "an unsigned 128 bit integer", "little-endian", 16, "0x01020304050607080910111213141516", r"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01";
317 put_i128, i128, to_be_bytes, "a signed 128 bit integer", "big-endian", 16, "0x01020304050607080910111213141516", r"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16";
318 put_i128_le, i128, to_le_bytes, "a signed 128 bit integer", "little-endian", 16, "0x01020304050607080910111213141516", r"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01";
319 }
320
321 /// Writes an unsigned n-byte integer to `self` in big-endian byte order.
322 ///
323 /// The current position is advanced by `nbytes`.
324 ///
325 /// # Examples
326 ///
327 /// ```
328 /// use ntex_bytes::BufMut;
329 ///
330 /// let mut buf = vec![];
331 /// buf.put_uint(0x010203, 3);
332 /// assert_eq!(buf, b"\x01\x02\x03");
333 /// ```
334 ///
335 /// # Panics
336 ///
337 /// This function panics if there is not enough remaining capacity in
338 /// `self`, or if `nbytes > 8`.
339 #[inline]
340 fn put_uint(&mut self, n: u64, nbytes: usize) {
341 self.put_slice(&n.to_be_bytes()[mem::size_of_val(&n) - nbytes..]);
342 }
343
344 /// Writes an unsigned n-byte integer to `self` in the little-endian byte order.
345 ///
346 /// The current position is advanced by `nbytes`.
347 ///
348 /// # Examples
349 ///
350 /// ```
351 /// use ntex_bytes::BufMut;
352 ///
353 /// let mut buf = vec![];
354 /// buf.put_uint_le(0x010203, 3);
355 /// assert_eq!(buf, b"\x03\x02\x01");
356 /// ```
357 ///
358 /// # Panics
359 ///
360 /// This function panics if there is not enough remaining capacity in
361 /// `self`, or if `nbytes > 8`.
362 #[inline]
363 fn put_uint_le(&mut self, n: u64, nbytes: usize) {
364 self.put_slice(&n.to_le_bytes()[0..nbytes]);
365 }
366
367 /// Writes a signed n-byte integer to `self` in big-endian byte order.
368 ///
369 /// The current position is advanced by `nbytes`.
370 ///
371 /// # Examples
372 ///
373 /// ```
374 /// use ntex_bytes::BufMut;
375 ///
376 /// let mut buf = vec![];
377 /// buf.put_int(0x010203, 3);
378 /// assert_eq!(buf, b"\x01\x02\x03");
379 /// ```
380 ///
381 /// # Panics
382 ///
383 /// This function panics if there is not enough remaining capacity in
384 /// `self`, or if `nbytes > 8`.
385 #[inline]
386 fn put_int(&mut self, n: i64, nbytes: usize) {
387 self.put_slice(&n.to_be_bytes()[mem::size_of_val(&n) - nbytes..]);
388 }
389
390 /// Writes a signed n-byte integer to `self` in little-endian byte order.
391 ///
392 /// The current position is advanced by `nbytes`.
393 ///
394 /// # Examples
395 ///
396 /// ```
397 /// use ntex_bytes::BufMut;
398 ///
399 /// let mut buf = vec![];
400 /// buf.put_int_le(0x010203, 3);
401 /// assert_eq!(buf, b"\x03\x02\x01");
402 /// ```
403 ///
404 /// # Panics
405 ///
406 /// This function panics if there is not enough remaining capacity in
407 /// `self`, or if `nbytes > 8`.
408 #[inline]
409 fn put_int_le(&mut self, n: i64, nbytes: usize) {
410 self.put_slice(&n.to_le_bytes()[0..nbytes]);
411 }
412
413 /// Writes an IEEE754 single-precision (4 bytes) floating point number to
414 /// `self` in big-endian byte order.
415 ///
416 /// The current position is advanced by 4.
417 ///
418 /// # Examples
419 ///
420 /// ```
421 /// use ntex_bytes::BufMut;
422 ///
423 /// let mut buf = vec![];
424 /// buf.put_f32(1.2f32);
425 /// assert_eq!(buf, b"\x3F\x99\x99\x9A");
426 /// ```
427 ///
428 /// # Panics
429 ///
430 /// This function panics if there is not enough remaining capacity in
431 /// `self`.
432 #[inline]
433 fn put_f32(&mut self, n: f32) {
434 self.put_u32(n.to_bits());
435 }
436
437 /// Writes an IEEE754 single-precision (4 bytes) floating point number to
438 /// `self` in little-endian byte order.
439 ///
440 /// The current position is advanced by 4.
441 ///
442 /// # Examples
443 ///
444 /// ```
445 /// use ntex_bytes::BufMut;
446 ///
447 /// let mut buf = vec![];
448 /// buf.put_f32_le(1.2f32);
449 /// assert_eq!(buf, b"\x9A\x99\x99\x3F");
450 /// ```
451 ///
452 /// # Panics
453 ///
454 /// This function panics if there is not enough remaining capacity in
455 /// `self`.
456 #[inline]
457 fn put_f32_le(&mut self, n: f32) {
458 self.put_u32_le(n.to_bits());
459 }
460
461 /// Writes an IEEE754 double-precision (8 bytes) floating point number to
462 /// `self` in big-endian byte order.
463 ///
464 /// The current position is advanced by 8.
465 ///
466 /// # Examples
467 ///
468 /// ```
469 /// use ntex_bytes::BufMut;
470 ///
471 /// let mut buf = vec![];
472 /// buf.put_f64(1.2f64);
473 /// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
474 /// ```
475 ///
476 /// # Panics
477 ///
478 /// This function panics if there is not enough remaining capacity in
479 /// `self`.
480 #[inline]
481 fn put_f64(&mut self, n: f64) {
482 self.put_u64(n.to_bits());
483 }
484
485 /// Writes an IEEE754 double-precision (8 bytes) floating point number to
486 /// `self` in little-endian byte order.
487 ///
488 /// The current position is advanced by 8.
489 ///
490 /// # Examples
491 ///
492 /// ```
493 /// use ntex_bytes::BufMut;
494 ///
495 /// let mut buf = vec![];
496 /// buf.put_f64_le(1.2f64);
497 /// assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
498 /// ```
499 ///
500 /// # Panics
501 ///
502 /// This function panics if there is not enough remaining capacity in
503 /// `self`.
504 #[inline]
505 fn put_f64_le(&mut self, n: f64) {
506 self.put_u64_le(n.to_bits());
507 }
508}
509
510macro_rules! deref_forward_bufmut {
511 () => {
512 fn remaining_mut(&self) -> usize {
513 (**self).remaining_mut()
514 }
515
516 fn chunk_mut(&mut self) -> &mut UninitSlice {
517 (**self).chunk_mut()
518 }
519
520 unsafe fn advance_mut(&mut self, cnt: usize) {
521 (**self).advance_mut(cnt);
522 }
523
524 fn put_slice(&mut self, src: &[u8]) {
525 (**self).put_slice(src);
526 }
527
528 fn put_u8(&mut self, n: u8) {
529 (**self).put_u8(n);
530 }
531
532 fn put_i8(&mut self, n: i8) {
533 (**self).put_i8(n);
534 }
535 };
536}
537
538impl<T: BufMut + ?Sized> BufMut for &mut T {
539 deref_forward_bufmut!();
540}
541
542impl<T: BufMut + ?Sized> BufMut for Box<T> {
543 deref_forward_bufmut!();
544}
545
546impl BufMut for Vec<u8> {
547 #[inline]
548 fn remaining_mut(&self) -> usize {
549 usize::MAX - self.len()
550 }
551
552 #[inline]
553 unsafe fn advance_mut(&mut self, cnt: usize) {
554 let len = self.len();
555 let remaining = self.capacity() - len;
556 // only the spare capacity exposed by `chunk_mut` can be initialized
557 assert!(
558 cnt <= remaining,
559 "cannot advance past the capacity of the buffer, cnt:{cnt} remaining:{remaining}"
560 );
561
562 self.set_len(len + cnt);
563 }
564
565 #[inline]
566 fn chunk_mut(&mut self) -> &mut UninitSlice {
567 if self.capacity() == self.len() {
568 self.reserve(64); // Grow the vec
569 }
570
571 let cap = self.capacity();
572 let len = self.len();
573
574 let ptr = self.as_mut_ptr();
575 // SAFETY: The vector owns its allocation exclusively, and `len..cap` is its writable spare
576 // capacity.
577 unsafe { &mut UninitSlice::from_raw_parts_mut(ptr, cap)[len..] }
578 }
579}
580
581impl BufMut for &mut [u8] {
582 #[inline]
583 fn remaining_mut(&self) -> usize {
584 self.len()
585 }
586
587 #[inline]
588 fn chunk_mut(&mut self) -> &mut UninitSlice {
589 // SAFETY: The exclusive slice covers these bytes; `UninitSlice` cannot read or
590 // de-initialize them.
591 unsafe { UninitSlice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
592 }
593
594 #[inline]
595 unsafe fn advance_mut(&mut self, cnt: usize) {
596 // Lifetime dance taken from `impl Write for &mut [u8]`.
597 let (_, b) = core::mem::take(self).split_at_mut(cnt);
598 *self = b;
599 }
600
601 #[inline]
602 fn put_slice(&mut self, src: &[u8]) {
603 self[..src.len()].copy_from_slice(src);
604 // SAFETY: The copied prefix is initialized and `src.len()` fits the destination checked by
605 // slicing above.
606 unsafe {
607 self.advance_mut(src.len());
608 }
609 }
610}
611
612// The existence of this function makes the compiler catch if the BufMut
613// trait is "object-safe" or not.
614fn _assert_trait_object(_b: &dyn BufMut) {}
615
616#[cfg(test)]
617#[allow(unused_allocation, warnings)]
618mod tests {
619 use super::*;
620 use crate::BytesMut;
621
622 /// STATEMENT: `BufMut` implementations write expected bytes and report remaining writable capacity.
623 ///
624 /// HOW:
625 /// - Write through vectors, mutable slices, boxed slices, and `BytesMut`, checking bytes, chunk access, and capacity after advancement.
626 /// - Encode integer and floating-point values in both byte orders and compare each exact byte sequence.
627 #[test]
628 #[allow(clippy::needless_borrow, clippy::too_many_lines)]
629 fn buf_mut_tests() {
630 let mut buf = vec![];
631 buf.put_u8(0x01);
632 assert_eq!(buf, b"\x01");
633
634 assert_eq!(buf.remaining_mut(), usize::MAX - 1);
635 assert_eq!((&buf).remaining_mut(), usize::MAX - 1);
636 assert_eq!(Box::new(buf).remaining_mut(), usize::MAX - 1);
637
638 let mut buf = [b'1'; 10];
639 let mut b = buf.as_mut();
640 assert_eq!(b.remaining_mut(), 10);
641 assert!(b.has_remaining_mut());
642 b.put_slice(b"123");
643 assert_eq!(&buf[..], b"1231111111");
644
645 let mut b: &mut [u8] = buf.as_mut();
646 let chunk = b.chunk_mut();
647 chunk.write_byte(0, b'9');
648 assert_eq!(&buf[..], b"9231111111");
649
650 let mut b = buf.as_mut();
651 let chunk = b.chunk_mut();
652 chunk.copy_from_slice(b"0000000000");
653 assert_eq!(&buf[..], b"0000000000");
654
655 let mut b = buf.as_mut();
656 assert_eq!(format!("{:?}", b.chunk_mut()), "UninitSlice[...]");
657
658 let b = buf.as_mut();
659 let mut bb = Box::new(b);
660 // SAFETY: The boxed slice has ten initialized bytes, so advancing by one stays within bounds.
661 unsafe { bb.advance_mut(1) };
662 let chunk = bb.chunk_mut();
663 chunk.copy_from_slice(b"111111111");
664 assert_eq!(&buf[..], b"0111111111");
665
666 let mut buf = BytesMut::new();
667 buf.put_u8(0x01);
668 assert_eq!(buf, b"\x01"[..]);
669
670 let mut buf = BytesMut::new();
671 buf.put_u8(0x01);
672 assert_eq!(buf, b"\x01"[..]);
673
674 let mut buf = vec![];
675 buf.put_i8(0x01);
676 assert_eq!(buf, b"\x01");
677
678 let mut buf = BytesMut::new();
679 buf.put_i8(0x01);
680 assert_eq!(buf, b"\x01"[..]);
681
682 let mut buf = BytesMut::new();
683 buf.put_i8(0x01);
684 assert_eq!(buf, b"\x01"[..]);
685 assert_eq!((&mut buf).remaining_mut(), crate::storage::MIN_CAPACITY - 1);
686 let chunk = (&mut buf).chunk_mut();
687 chunk.write_byte(0, b'9');
688 // SAFETY: The first spare byte was initialized by `write_byte` immediately above.
689 unsafe { (&mut buf).advance_mut(1) };
690 assert_eq!((&mut buf).remaining_mut(), crate::storage::MIN_CAPACITY - 2);
691
692 let mut buf = vec![];
693 buf.put_i16(0x0809);
694 assert_eq!(buf, b"\x08\x09");
695
696 let mut buf = vec![];
697 buf.put_i16_le(0x0809);
698 assert_eq!(buf, b"\x09\x08");
699
700 let mut buf = vec![];
701 buf.put_u32(0x0809_A0A1);
702 assert_eq!(buf, b"\x08\x09\xA0\xA1");
703
704 let mut buf = vec![];
705 buf.put_i32(0x0809_A0A1);
706 assert_eq!(buf, b"\x08\x09\xA0\xA1");
707
708 let mut buf = vec![];
709 buf.put_i32_le(0x0809_A0A1);
710 assert_eq!(buf, b"\xA1\xA0\x09\x08");
711
712 let mut buf = vec![];
713 buf.put_u64(0x0102_0304_0506_0708);
714 assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
715
716 let mut buf = vec![];
717 buf.put_u64_le(0x0102_0304_0506_0708);
718 assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
719
720 let mut buf = vec![];
721 buf.put_i64(0x0102_0304_0506_0708);
722 assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
723
724 let mut buf = vec![];
725 buf.put_i64_le(0x0102_0304_0506_0708);
726 assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
727
728 let mut buf = vec![];
729 buf.put_u128(0x0102_0304_0506_0708_0910_1112_1314_1516);
730 assert_eq!(
731 buf,
732 b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16"
733 );
734
735 let mut buf = vec![];
736 buf.put_u128_le(0x0102_0304_0506_0708_0910_1112_1314_1516);
737 assert_eq!(
738 buf,
739 b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01"
740 );
741
742 let mut buf = vec![];
743 buf.put_i128(0x0102_0304_0506_0708_0910_1112_1314_1516);
744 assert_eq!(
745 buf,
746 b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16"
747 );
748
749 let mut buf = vec![];
750 buf.put_i128_le(0x0102_0304_0506_0708_0910_1112_1314_1516);
751 assert_eq!(
752 buf,
753 b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01"
754 );
755
756 let mut buf = vec![];
757 buf.put_uint(0x01_0203, 3);
758 assert_eq!(buf, b"\x01\x02\x03");
759
760 let mut buf = vec![];
761 buf.put_uint_le(0x01_0203, 3);
762 assert_eq!(buf, b"\x03\x02\x01");
763
764 let mut buf = vec![];
765 buf.put_int(0x01_0203, 3);
766 assert_eq!(buf, b"\x01\x02\x03");
767
768 let mut buf = vec![];
769 buf.put_int_le(0x01_0203, 3);
770 assert_eq!(buf, b"\x03\x02\x01");
771
772 let mut buf = vec![];
773 buf.put_f32(1.2f32);
774 assert_eq!(buf, b"\x3F\x99\x99\x9A");
775
776 let mut buf = vec![];
777 buf.put_f32_le(1.2f32);
778 assert_eq!(buf, b"\x9A\x99\x99\x3F");
779
780 let mut buf = vec![];
781 buf.put_f64(1.2f64);
782 assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
783
784 let mut buf = vec![];
785 buf.put_f64_le(1.2f64);
786 assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
787 }
788}