webrtc_util/marshal/
exact_size_buf.rs

1// FIXME(regexident):
2// Replace with `bytes::ExactSizeBuf` once merged:
3// https://github.com/tokio-rs/bytes/pull/496
4
5use bytes::buf::{Chain, Take};
6use bytes::{Bytes, BytesMut};
7
8/// A trait for buffers that know their exact length.
9pub trait ExactSizeBuf {
10    /// Returns the exact length of the buffer.
11    fn len(&self) -> usize;
12
13    /// Returns `true` if the buffer is empty.
14    ///
15    /// This method has a default implementation using `ExactSizeBuf::len()`,
16    /// so you don't need to implement it yourself.
17    #[inline]
18    fn is_empty(&self) -> bool {
19        self.len() == 0
20    }
21}
22
23impl ExactSizeBuf for Bytes {
24    #[inline]
25    fn len(&self) -> usize {
26        Bytes::len(self)
27    }
28
29    #[inline]
30    fn is_empty(&self) -> bool {
31        Bytes::is_empty(self)
32    }
33}
34
35impl ExactSizeBuf for BytesMut {
36    #[inline]
37    fn len(&self) -> usize {
38        BytesMut::len(self)
39    }
40
41    #[inline]
42    fn is_empty(&self) -> bool {
43        BytesMut::is_empty(self)
44    }
45}
46
47impl ExactSizeBuf for [u8] {
48    #[inline]
49    fn len(&self) -> usize {
50        <[u8]>::len(self)
51    }
52
53    #[inline]
54    fn is_empty(&self) -> bool {
55        <[u8]>::is_empty(self)
56    }
57}
58
59impl<T, U> ExactSizeBuf for Chain<T, U>
60where
61    T: ExactSizeBuf,
62    U: ExactSizeBuf,
63{
64    fn len(&self) -> usize {
65        let first_ref = self.first_ref();
66        let last_ref = self.last_ref();
67
68        first_ref.len() + last_ref.len()
69    }
70
71    fn is_empty(&self) -> bool {
72        let first_ref = self.first_ref();
73        let last_ref = self.last_ref();
74
75        first_ref.is_empty() && last_ref.is_empty()
76    }
77}
78
79impl<T> ExactSizeBuf for Take<T>
80where
81    T: ExactSizeBuf,
82{
83    fn len(&self) -> usize {
84        let inner_ref = self.get_ref();
85        let limit = self.limit();
86
87        limit.min(inner_ref.len())
88    }
89
90    fn is_empty(&self) -> bool {
91        let inner_ref = self.get_ref();
92        let limit = self.limit();
93
94        (limit == 0) || inner_ref.is_empty()
95    }
96}