mco_redis/bytes/buf/
buf_impl.rs

1use std::{cmp, mem, ptr};
2
3macro_rules! buf_get_impl {
4    ($this:ident, $typ:tt::$conv:tt) => {{
5        const SIZE: usize = mem::size_of::<$typ>();
6        // try to convert directly from the bytes
7        // this Option<ret> trick is to avoid keeping a borrow on self
8        // when advance() is called (mut borrow) and to call bytes() only once
9        let ret = $this
10            .chunk()
11            .get(..SIZE)
12            .map(|src| unsafe { $typ::$conv(*(src as *const _ as *const [_; SIZE])) });
13
14        if let Some(ret) = ret {
15            // if the direct conversion was possible, advance and return
16            $this.advance(SIZE);
17            return ret;
18        } else {
19            // if not we copy the bytes in a temp buffer then convert
20            let mut buf = [0; SIZE];
21            $this.copy_to_slice(&mut buf); // (do the advance)
22            return $typ::$conv(buf);
23        }
24    }};
25    (le => $this:ident, $typ:tt, $len_to_read:expr) => {{
26        debug_assert!(mem::size_of::<$typ>() >= $len_to_read);
27
28        // The same trick as above does not improve the best case speed.
29        // It seems to be linked to the way the method is optimised by the compiler
30        let mut buf = [0; (mem::size_of::<$typ>())];
31        $this.copy_to_slice(&mut buf[..($len_to_read)]);
32        return $typ::from_le_bytes(buf);
33    }};
34    (be => $this:ident, $typ:tt, $len_to_read:expr) => {{
35        debug_assert!(mem::size_of::<$typ>() >= $len_to_read);
36
37        let mut buf = [0; (mem::size_of::<$typ>())];
38        $this.copy_to_slice(&mut buf[mem::size_of::<$typ>() - ($len_to_read)..]);
39        return $typ::from_be_bytes(buf);
40    }};
41}
42
43/// Read bytes from a buffer.
44///
45/// A buffer stores bytes in memory such that read operations are infallible.
46/// The underlying storage may or may not be in contiguous memory. A `Buf` value
47/// is a cursor into the buffer. Reading from `Buf` advances the cursor
48/// position. It can be thought of as an efficient `Iterator` for collections of
49/// bytes.
50///
51/// The simplest `Buf` is a `&[u8]`.
52///
53/// ```
54/// use mco_redis::bytes::Buf;
55///
56/// let mut buf = &b"hello world"[..];
57///
58/// assert_eq!(b'h', buf.get_u8());
59/// assert_eq!(b'e', buf.get_u8());
60/// assert_eq!(b'l', buf.get_u8());
61///
62/// let mut rest = [0; 8];
63/// buf.copy_to_slice(&mut rest);
64///
65/// assert_eq!(&rest[..], &b"lo world"[..]);
66/// ```
67pub trait Buf {
68    /// Returns the number of bytes between the current position and the end of
69    /// the buffer.
70    ///
71    /// This value is greater than or equal to the length of the slice returned
72    /// by `bytes`.
73    ///
74    /// # Examples
75    ///
76    /// ```
77    /// use mco_redis::bytes::Buf;
78    ///
79    /// let mut buf = &b"hello world"[..];
80    ///
81    /// assert_eq!(buf.remaining(), 11);
82    ///
83    /// buf.get_u8();
84    ///
85    /// assert_eq!(buf.remaining(), 10);
86    /// ```
87    ///
88    /// # Implementer notes
89    ///
90    /// Implementations of `remaining` should ensure that the return value does
91    /// not change unless a call is made to `advance` or any other function that
92    /// is documented to change the `Buf`'s current position.
93    fn remaining(&self) -> usize;
94
95    /// Returns a slice starting at the current position and of length between 0
96    /// and `Buf::remaining()`. Note that this *can* return shorter slice (this allows
97    /// non-continuous internal representation).
98    ///
99    /// This is a lower level function. Most operations are done with other
100    /// functions.
101    ///
102    /// # Examples
103    ///
104    /// ```
105    /// use mco_redis::bytes::Buf;
106    ///
107    /// let mut buf = &b"hello world"[..];
108    ///
109    /// assert_eq!(buf.chunk(), &b"hello world"[..]);
110    ///
111    /// buf.advance(6);
112    ///
113    /// assert_eq!(buf.chunk(), &b"world"[..]);
114    /// ```
115    ///
116    /// # Implementer notes
117    ///
118    /// This function should never panic. Once the end of the buffer is reached,
119    /// i.e., `Buf::remaining` returns 0, calls to `chunk` should return an
120    /// empty slice.
121    fn chunk(&self) -> &[u8];
122
123    /// Advance the internal cursor of the Buf
124    ///
125    /// The next call to `bytes` will return a slice starting `cnt` bytes
126    /// further into the underlying buffer.
127    ///
128    /// # Examples
129    ///
130    /// ```
131    /// use mco_redis::bytes::Buf;
132    ///
133    /// let mut buf = &b"hello world"[..];
134    ///
135    /// assert_eq!(buf.chunk(), &b"hello world"[..]);
136    ///
137    /// buf.advance(6);
138    ///
139    /// assert_eq!(buf.chunk(), &b"world"[..]);
140    /// ```
141    ///
142    /// # Panics
143    ///
144    /// This function **may** panic if `cnt > self.remaining()`.
145    ///
146    /// # Implementer notes
147    ///
148    /// It is recommended for implementations of `advance` to panic if `cnt >
149    /// self.remaining()`. If the implementation does not panic, the call must
150    /// behave as if `cnt == self.remaining()`.
151    ///
152    /// A call with `cnt == 0` should never panic and be a no-op.
153    fn advance(&mut self, cnt: usize);
154
155    /// Returns true if there are any more bytes to consume
156    ///
157    /// This is equivalent to `self.remaining() != 0`.
158    ///
159    /// # Examples
160    ///
161    /// ```
162    /// use mco_redis::bytes::Buf;
163    ///
164    /// let mut buf = &b"a"[..];
165    ///
166    /// assert!(buf.has_remaining());
167    ///
168    /// buf.get_u8();
169    ///
170    /// assert!(!buf.has_remaining());
171    /// ```
172    fn has_remaining(&self) -> bool {
173        self.remaining() > 0
174    }
175
176    /// Copies bytes from `self` into `dst`.
177    ///
178    /// The cursor is advanced by the number of bytes copied. `self` must have
179    /// enough remaining bytes to fill `dst`.
180    ///
181    /// # Examples
182    ///
183    /// ```
184    /// use mco_redis::bytes::Buf;
185    ///
186    /// let mut buf = &b"hello world"[..];
187    /// let mut dst = [0; 5];
188    ///
189    /// buf.copy_to_slice(&mut dst);
190    /// assert_eq!(&b"hello"[..], &dst);
191    /// assert_eq!(6, buf.remaining());
192    /// ```
193    ///
194    /// # Panics
195    ///
196    /// This function panics if `self.remaining() < dst.len()`
197    fn copy_to_slice(&mut self, dst: &mut [u8]) {
198        let mut off = 0;
199
200        assert!(self.remaining() >= dst.len());
201
202        while off < dst.len() {
203            let cnt;
204
205            unsafe {
206                let src = self.chunk();
207                cnt = cmp::min(src.len(), dst.len() - off);
208
209                ptr::copy_nonoverlapping(src.as_ptr(), dst[off..].as_mut_ptr(), cnt);
210
211                off += cnt;
212            }
213
214            self.advance(cnt);
215        }
216    }
217
218    /// Gets an unsigned 8 bit integer from `self`.
219    ///
220    /// The current position is advanced by 1.
221    ///
222    /// # Examples
223    ///
224    /// ```
225    /// use mco_redis::bytes::Buf;
226    ///
227    /// let mut buf = &b"\x08 hello"[..];
228    /// assert_eq!(8, buf.get_u8());
229    /// ```
230    ///
231    /// # Panics
232    ///
233    /// This function panics if there is no more remaining data in `self`.
234    #[inline]
235    fn get_u8(&mut self) -> u8 {
236        assert!(self.remaining() >= 1);
237        let ret = self.chunk()[0];
238        self.advance(1);
239        ret
240    }
241
242    /// Gets a signed 8 bit integer from `self`.
243    ///
244    /// The current position is advanced by 1.
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// use mco_redis::bytes::Buf;
250    ///
251    /// let mut buf = &b"\x08 hello"[..];
252    /// assert_eq!(8, buf.get_i8());
253    /// ```
254    ///
255    /// # Panics
256    ///
257    /// This function panics if there is no more remaining data in `self`.
258    #[inline]
259    fn get_i8(&mut self) -> i8 {
260        assert!(self.remaining() >= 1);
261        let ret = self.chunk()[0] as i8;
262        self.advance(1);
263        ret
264    }
265
266    /// Gets an unsigned 16 bit integer from `self` in big-endian byte order.
267    ///
268    /// The current position is advanced by 2.
269    ///
270    /// # Examples
271    ///
272    /// ```
273    /// use mco_redis::bytes::Buf;
274    ///
275    /// let mut buf = &b"\x08\x09 hello"[..];
276    /// assert_eq!(0x0809, buf.get_u16());
277    /// ```
278    ///
279    /// # Panics
280    ///
281    /// This function panics if there is not enough remaining data in `self`.
282    #[inline]
283    fn get_u16(&mut self) -> u16 {
284        buf_get_impl!(self, u16::from_be_bytes);
285    }
286
287    /// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
288    ///
289    /// The current position is advanced by 2.
290    ///
291    /// # Examples
292    ///
293    /// ```
294    /// use mco_redis::bytes::Buf;
295    ///
296    /// let mut buf = &b"\x09\x08 hello"[..];
297    /// assert_eq!(0x0809, buf.get_u16_le());
298    /// ```
299    ///
300    /// # Panics
301    ///
302    /// This function panics if there is not enough remaining data in `self`.
303    #[inline]
304    fn get_u16_le(&mut self) -> u16 {
305        buf_get_impl!(self, u16::from_le_bytes);
306    }
307
308    /// Gets a signed 16 bit integer from `self` in big-endian byte order.
309    ///
310    /// The current position is advanced by 2.
311    ///
312    /// # Examples
313    ///
314    /// ```
315    /// use mco_redis::bytes::Buf;
316    ///
317    /// let mut buf = &b"\x08\x09 hello"[..];
318    /// assert_eq!(0x0809, buf.get_i16());
319    /// ```
320    ///
321    /// # Panics
322    ///
323    /// This function panics if there is not enough remaining data in `self`.
324    #[inline]
325    fn get_i16(&mut self) -> i16 {
326        buf_get_impl!(self, i16::from_be_bytes);
327    }
328
329    /// Gets a signed 16 bit integer from `self` in little-endian byte order.
330    ///
331    /// The current position is advanced by 2.
332    ///
333    /// # Examples
334    ///
335    /// ```
336    /// use mco_redis::bytes::Buf;
337    ///
338    /// let mut buf = &b"\x09\x08 hello"[..];
339    /// assert_eq!(0x0809, buf.get_i16_le());
340    /// ```
341    ///
342    /// # Panics
343    ///
344    /// This function panics if there is not enough remaining data in `self`.
345    #[inline]
346    fn get_i16_le(&mut self) -> i16 {
347        buf_get_impl!(self, i16::from_le_bytes);
348    }
349
350    /// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
351    ///
352    /// The current position is advanced by 4.
353    ///
354    /// # Examples
355    ///
356    /// ```
357    /// use mco_redis::bytes::Buf;
358    ///
359    /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
360    /// assert_eq!(0x0809A0A1, buf.get_u32());
361    /// ```
362    ///
363    /// # Panics
364    ///
365    /// This function panics if there is not enough remaining data in `self`.
366    #[inline]
367    fn get_u32(&mut self) -> u32 {
368        buf_get_impl!(self, u32::from_be_bytes);
369    }
370
371    /// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
372    ///
373    /// The current position is advanced by 4.
374    ///
375    /// # Examples
376    ///
377    /// ```
378    /// use mco_redis::bytes::Buf;
379    ///
380    /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
381    /// assert_eq!(0x0809A0A1, buf.get_u32_le());
382    /// ```
383    ///
384    /// # Panics
385    ///
386    /// This function panics if there is not enough remaining data in `self`.
387    #[inline]
388    fn get_u32_le(&mut self) -> u32 {
389        buf_get_impl!(self, u32::from_le_bytes);
390    }
391
392    /// Gets a signed 32 bit integer from `self` in big-endian byte order.
393    ///
394    /// The current position is advanced by 4.
395    ///
396    /// # Examples
397    ///
398    /// ```
399    /// use mco_redis::bytes::Buf;
400    ///
401    /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
402    /// assert_eq!(0x0809A0A1, buf.get_i32());
403    /// ```
404    ///
405    /// # Panics
406    ///
407    /// This function panics if there is not enough remaining data in `self`.
408    #[inline]
409    fn get_i32(&mut self) -> i32 {
410        buf_get_impl!(self, i32::from_be_bytes);
411    }
412
413    /// Gets a signed 32 bit integer from `self` in little-endian byte order.
414    ///
415    /// The current position is advanced by 4.
416    ///
417    /// # Examples
418    ///
419    /// ```
420    /// use mco_redis::bytes::Buf;
421    ///
422    /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
423    /// assert_eq!(0x0809A0A1, buf.get_i32_le());
424    /// ```
425    ///
426    /// # Panics
427    ///
428    /// This function panics if there is not enough remaining data in `self`.
429    #[inline]
430    fn get_i32_le(&mut self) -> i32 {
431        buf_get_impl!(self, i32::from_le_bytes);
432    }
433
434    /// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
435    ///
436    /// The current position is advanced by 8.
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// use mco_redis::bytes::Buf;
442    ///
443    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
444    /// assert_eq!(0x0102030405060708, buf.get_u64());
445    /// ```
446    ///
447    /// # Panics
448    ///
449    /// This function panics if there is not enough remaining data in `self`.
450    #[inline]
451    fn get_u64(&mut self) -> u64 {
452        buf_get_impl!(self, u64::from_be_bytes);
453    }
454
455    /// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
456    ///
457    /// The current position is advanced by 8.
458    ///
459    /// # Examples
460    ///
461    /// ```
462    /// use mco_redis::bytes::Buf;
463    ///
464    /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
465    /// assert_eq!(0x0102030405060708, buf.get_u64_le());
466    /// ```
467    ///
468    /// # Panics
469    ///
470    /// This function panics if there is not enough remaining data in `self`.
471    #[inline]
472    fn get_u64_le(&mut self) -> u64 {
473        buf_get_impl!(self, u64::from_le_bytes);
474    }
475
476    /// Gets a signed 64 bit integer from `self` in big-endian byte order.
477    ///
478    /// The current position is advanced by 8.
479    ///
480    /// # Examples
481    ///
482    /// ```
483    /// use mco_redis::bytes::Buf;
484    ///
485    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
486    /// assert_eq!(0x0102030405060708, buf.get_i64());
487    /// ```
488    ///
489    /// # Panics
490    ///
491    /// This function panics if there is not enough remaining data in `self`.
492    #[inline]
493    fn get_i64(&mut self) -> i64 {
494        buf_get_impl!(self, i64::from_be_bytes);
495    }
496
497    /// Gets a signed 64 bit integer from `self` in little-endian byte order.
498    ///
499    /// The current position is advanced by 8.
500    ///
501    /// # Examples
502    ///
503    /// ```
504    /// use mco_redis::bytes::Buf;
505    ///
506    /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
507    /// assert_eq!(0x0102030405060708, buf.get_i64_le());
508    /// ```
509    ///
510    /// # Panics
511    ///
512    /// This function panics if there is not enough remaining data in `self`.
513    #[inline]
514    fn get_i64_le(&mut self) -> i64 {
515        buf_get_impl!(self, i64::from_le_bytes);
516    }
517
518    /// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
519    ///
520    /// The current position is advanced by 16.
521    ///
522    /// # Examples
523    ///
524    /// ```
525    /// use mco_redis::bytes::Buf;
526    ///
527    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
528    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
529    /// ```
530    ///
531    /// # Panics
532    ///
533    /// This function panics if there is not enough remaining data in `self`.
534    #[inline]
535    fn get_u128(&mut self) -> u128 {
536        buf_get_impl!(self, u128::from_be_bytes);
537    }
538
539    /// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
540    ///
541    /// The current position is advanced by 16.
542    ///
543    /// # Examples
544    ///
545    /// ```
546    /// use mco_redis::bytes::Buf;
547    ///
548    /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
549    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
550    /// ```
551    ///
552    /// # Panics
553    ///
554    /// This function panics if there is not enough remaining data in `self`.
555    #[inline]
556    fn get_u128_le(&mut self) -> u128 {
557        buf_get_impl!(self, u128::from_le_bytes);
558    }
559
560    /// Gets a signed 128 bit integer from `self` in big-endian byte order.
561    ///
562    /// The current position is advanced by 16.
563    ///
564    /// # Examples
565    ///
566    /// ```
567    /// use mco_redis::bytes::Buf;
568    ///
569    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
570    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
571    /// ```
572    ///
573    /// # Panics
574    ///
575    /// This function panics if there is not enough remaining data in `self`.
576    #[inline]
577    fn get_i128(&mut self) -> i128 {
578        buf_get_impl!(self, i128::from_be_bytes);
579    }
580
581    /// Gets a signed 128 bit integer from `self` in little-endian byte order.
582    ///
583    /// The current position is advanced by 16.
584    ///
585    /// # Examples
586    ///
587    /// ```
588    /// use mco_redis::bytes::Buf;
589    ///
590    /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
591    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
592    /// ```
593    ///
594    /// # Panics
595    ///
596    /// This function panics if there is not enough remaining data in `self`.
597    #[inline]
598    fn get_i128_le(&mut self) -> i128 {
599        buf_get_impl!(self, i128::from_le_bytes);
600    }
601
602    /// Gets an unsigned n-byte integer from `self` in big-endian byte order.
603    ///
604    /// The current position is advanced by `nbytes`.
605    ///
606    /// # Examples
607    ///
608    /// ```
609    /// use mco_redis::bytes::Buf;
610    ///
611    /// let mut buf = &b"\x01\x02\x03 hello"[..];
612    /// assert_eq!(0x010203, buf.get_uint(3));
613    /// ```
614    ///
615    /// # Panics
616    ///
617    /// This function panics if there is not enough remaining data in `self`.
618    #[inline]
619    fn get_uint(&mut self, nbytes: usize) -> u64 {
620        buf_get_impl!(be => self, u64, nbytes);
621    }
622
623    /// Gets an unsigned n-byte integer from `self` in little-endian byte order.
624    ///
625    /// The current position is advanced by `nbytes`.
626    ///
627    /// # Examples
628    ///
629    /// ```
630    /// use mco_redis::bytes::Buf;
631    ///
632    /// let mut buf = &b"\x03\x02\x01 hello"[..];
633    /// assert_eq!(0x010203, buf.get_uint_le(3));
634    /// ```
635    ///
636    /// # Panics
637    ///
638    /// This function panics if there is not enough remaining data in `self`.
639    #[inline]
640    fn get_uint_le(&mut self, nbytes: usize) -> u64 {
641        buf_get_impl!(le => self, u64, nbytes);
642    }
643
644    /// Gets a signed n-byte integer from `self` in big-endian byte order.
645    ///
646    /// The current position is advanced by `nbytes`.
647    ///
648    /// # Examples
649    ///
650    /// ```
651    /// use mco_redis::bytes::Buf;
652    ///
653    /// let mut buf = &b"\x01\x02\x03 hello"[..];
654    /// assert_eq!(0x010203, buf.get_int(3));
655    /// ```
656    ///
657    /// # Panics
658    ///
659    /// This function panics if there is not enough remaining data in `self`.
660    #[inline]
661    fn get_int(&mut self, nbytes: usize) -> i64 {
662        buf_get_impl!(be => self, i64, nbytes);
663    }
664
665    /// Gets a signed n-byte integer from `self` in little-endian byte order.
666    ///
667    /// The current position is advanced by `nbytes`.
668    ///
669    /// # Examples
670    ///
671    /// ```
672    /// use mco_redis::bytes::Buf;
673    ///
674    /// let mut buf = &b"\x03\x02\x01 hello"[..];
675    /// assert_eq!(0x010203, buf.get_int_le(3));
676    /// ```
677    ///
678    /// # Panics
679    ///
680    /// This function panics if there is not enough remaining data in `self`.
681    #[inline]
682    fn get_int_le(&mut self, nbytes: usize) -> i64 {
683        buf_get_impl!(le => self, i64, nbytes);
684    }
685
686    /// Gets an IEEE754 single-precision (4 bytes) floating point number from
687    /// `self` in big-endian byte order.
688    ///
689    /// The current position is advanced by 4.
690    ///
691    /// # Examples
692    ///
693    /// ```
694    /// use mco_redis::bytes::Buf;
695    ///
696    /// let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
697    /// assert_eq!(1.2f32, buf.get_f32());
698    /// ```
699    ///
700    /// # Panics
701    ///
702    /// This function panics if there is not enough remaining data in `self`.
703    #[inline]
704    fn get_f32(&mut self) -> f32 {
705        f32::from_bits(Self::get_u32(self))
706    }
707
708    /// Gets an IEEE754 single-precision (4 bytes) floating point number from
709    /// `self` in little-endian byte order.
710    ///
711    /// The current position is advanced by 4.
712    ///
713    /// # Examples
714    ///
715    /// ```
716    /// use mco_redis::bytes::Buf;
717    ///
718    /// let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
719    /// assert_eq!(1.2f32, buf.get_f32_le());
720    /// ```
721    ///
722    /// # Panics
723    ///
724    /// This function panics if there is not enough remaining data in `self`.
725    #[inline]
726    fn get_f32_le(&mut self) -> f32 {
727        f32::from_bits(Self::get_u32_le(self))
728    }
729
730    /// Gets an IEEE754 double-precision (8 bytes) floating point number from
731    /// `self` in big-endian byte order.
732    ///
733    /// The current position is advanced by 8.
734    ///
735    /// # Examples
736    ///
737    /// ```
738    /// use mco_redis::bytes::Buf;
739    ///
740    /// let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
741    /// assert_eq!(1.2f64, buf.get_f64());
742    /// ```
743    ///
744    /// # Panics
745    ///
746    /// This function panics if there is not enough remaining data in `self`.
747    #[inline]
748    fn get_f64(&mut self) -> f64 {
749        f64::from_bits(Self::get_u64(self))
750    }
751
752    /// Gets an IEEE754 double-precision (8 bytes) floating point number from
753    /// `self` in little-endian byte order.
754    ///
755    /// The current position is advanced by 8.
756    ///
757    /// # Examples
758    ///
759    /// ```
760    /// use mco_redis::bytes::Buf;
761    ///
762    /// let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
763    /// assert_eq!(1.2f64, buf.get_f64_le());
764    /// ```
765    ///
766    /// # Panics
767    ///
768    /// This function panics if there is not enough remaining data in `self`.
769    #[inline]
770    fn get_f64_le(&mut self) -> f64 {
771        f64::from_bits(Self::get_u64_le(self))
772    }
773
774    /// Consumes remaining bytes inside self and returns new instance of `Bytes`
775    ///
776    /// # Examples
777    ///
778    /// ```
779    /// use mco_redis::bytes::{Buf};
780    ///
781    /// let bytes = "hello world".to_bytes();
782    /// assert_eq!(&bytes[..], &b"hello world"[..]);
783    /// ```
784    #[inline]
785    #[allow(clippy::wrong_self_convention)]
786    fn to_bytes(&mut self) -> crate::bytes::Bytes {
787        use super::BufMut;
788        let mut ret = crate::bytes::BytesMut::with_capacity(self.remaining());
789        ret.put(self);
790        ret.freeze()
791    }
792}
793
794impl<T: Buf + ?Sized> Buf for &mut T {
795    #[inline]
796    fn remaining(&self) -> usize {
797        (**self).remaining()
798    }
799
800    #[inline]
801    fn chunk(&self) -> &[u8] {
802        (**self).chunk()
803    }
804
805    #[inline]
806    fn advance(&mut self, cnt: usize) {
807        (**self).advance(cnt)
808    }
809}
810
811impl<T: Buf + ?Sized> Buf for Box<T> {
812    #[inline]
813    fn remaining(&self) -> usize {
814        (**self).remaining()
815    }
816
817    #[inline]
818    fn chunk(&self) -> &[u8] {
819        (**self).chunk()
820    }
821
822    fn advance(&mut self, cnt: usize) {
823        (**self).advance(cnt)
824    }
825}
826
827impl Buf for &[u8] {
828    #[inline]
829    fn remaining(&self) -> usize {
830        self.len()
831    }
832
833    #[inline]
834    fn chunk(&self) -> &[u8] {
835        self
836    }
837
838    #[inline]
839    fn advance(&mut self, cnt: usize) {
840        *self = &self[cnt..];
841    }
842}
843
844impl Buf for &str {
845    #[inline]
846    fn remaining(&self) -> usize {
847        self.len()
848    }
849
850    #[inline]
851    fn chunk(&self) -> &[u8] {
852        self.as_bytes()
853    }
854
855    #[inline]
856    fn advance(&mut self, cnt: usize) {
857        *self = &self[cnt..];
858    }
859}
860
861impl<T: AsRef<[u8]>> Buf for std::io::Cursor<T> {
862    fn remaining(&self) -> usize {
863        let len = self.get_ref().as_ref().len();
864        let pos = self.position();
865
866        if pos >= len as u64 {
867            return 0;
868        }
869
870        len - pos as usize
871    }
872
873    fn chunk(&self) -> &[u8] {
874        let len = self.get_ref().as_ref().len();
875        let pos = self.position();
876
877        if pos >= len as u64 {
878            return &[];
879        }
880
881        &self.get_ref().as_ref()[pos as usize..]
882    }
883
884    fn advance(&mut self, cnt: usize) {
885        let pos = (self.position() as usize)
886            .checked_add(cnt)
887            .expect("overflow");
888
889        assert!(pos <= self.get_ref().as_ref().len());
890        self.set_position(pos as u64);
891    }
892}
893
894// The existence of this function makes the compiler catch if the Buf
895// trait is "object-safe" or not.
896fn _assert_trait_object(_b: &dyn Buf) {}
897
898#[cfg(test)]
899mod tests {
900    use super::*;
901
902    #[test]
903    fn buf_tests() {
904        let mut buf = &b"a"[..];
905        assert!(buf.has_remaining());
906        buf.get_u8();
907        assert!(!buf.has_remaining());
908
909        let mut buf = &b"hello world"[..];
910        let mut dst = [0; 5];
911        buf.copy_to_slice(&mut dst);
912        assert_eq!(&b"hello"[..], &dst);
913        assert_eq!(6, buf.remaining());
914
915        let mut buf = Box::new(buf);
916        assert_eq!(buf.remaining(), 6);
917        assert_eq!(buf.chunk(), b" world");
918        buf.advance(1);
919        assert_eq!(buf.chunk(), b"world");
920
921        let mut buf = std::io::Cursor::new(b" world");
922        assert_eq!(buf.remaining(), 6);
923        assert_eq!(buf.chunk(), b" world");
924        buf.advance(1);
925        assert_eq!(buf.chunk(), b"world");
926        buf.advance(5);
927        assert_eq!(buf.remaining(), 0);
928        assert_eq!(buf.chunk(), b"");
929
930        let mut buf = &b"\x08 hello"[..];
931        assert_eq!(8, buf.get_u8());
932
933        let mut buf = &b"\x08 hello"[..];
934        assert_eq!(8, buf.get_i8());
935
936        let mut buf = &b"\x08\x09 hello"[..];
937        assert_eq!(0x0809, buf.get_u16());
938
939        let mut buf = &b"\x09\x08 hello"[..];
940        assert_eq!(0x0809, buf.get_u16_le());
941
942        let mut buf = &b"\x08\x09 hello"[..];
943        assert_eq!(0x0809, buf.get_i16());
944
945        let mut buf = &b"\x09\x08 hello"[..];
946        assert_eq!(0x0809, buf.get_i16_le());
947
948        let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
949        assert_eq!(0x0809A0A1, buf.get_u32());
950
951        let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
952        assert_eq!(0x0809A0A1, buf.get_u32_le());
953
954        let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
955        assert_eq!(0x0809A0A1, buf.get_i32());
956
957        let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
958        assert_eq!(0x0809A0A1, buf.get_i32_le());
959
960        let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
961        assert_eq!(0x0102030405060708, buf.get_u64());
962
963        let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
964        assert_eq!(0x0102030405060708, buf.get_u64_le());
965
966        let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
967        assert_eq!(0x0102030405060708, buf.get_i64());
968
969        let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
970        assert_eq!(0x0102030405060708, buf.get_i64_le());
971
972        let mut buf =
973            &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
974        assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
975
976        let mut buf =
977            &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
978        assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
979
980        let mut buf =
981            &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
982        assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
983
984        let mut buf =
985            &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
986        assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
987
988        let mut buf = &b"\x01\x02\x03 hello"[..];
989        assert_eq!(0x010203, buf.get_uint(3));
990
991        let mut buf = &b"\x03\x02\x01 hello"[..];
992        assert_eq!(0x010203, buf.get_uint_le(3));
993
994        let mut buf = &b"\x01\x02\x03 hello"[..];
995        assert_eq!(0x010203, buf.get_int(3));
996
997        let mut buf = &b"\x03\x02\x01 hello"[..];
998        assert_eq!(0x010203, buf.get_int_le(3));
999
1000        let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
1001        assert_eq!(1.2f32, buf.get_f32());
1002
1003        let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
1004        assert_eq!(1.2f32, buf.get_f32_le());
1005
1006        let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
1007        assert_eq!(1.2f64, buf.get_f64());
1008
1009        let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
1010        assert_eq!(1.2f64, buf.get_f64_le());
1011
1012        let bytes = "hello world".to_bytes();
1013        assert_eq!(&bytes[..], &b"hello world"[..]);
1014    }
1015}