layered_io/
bufferable.rs

1use std::ops::DerefMut;
2use std::pin::Pin;
3
4/// A trait to help with buffering on top of `ReadLayered` and `WriteLayered`.
5pub trait Bufferable {
6    /// Close the resource and abandon any pending buffered contents or errors.
7    fn abandon(&mut self);
8
9    /// A suggested size, in bytes, for buffering for performance.
10    #[inline]
11    fn suggested_buffer_size(&self) -> usize {
12        default_suggested_buffer_size(self)
13    }
14}
15
16/// Default implementation of `Bufferable::abandon`, which does nothing.
17#[inline]
18pub fn default_suggested_buffer_size<Inner: Bufferable + ?Sized>(_inner: &Inner) -> usize {
19    // At the time of this writing, this is the same as `DEFAULT_BUF_SIZE`
20    // in libstd.
21    0x2000
22}
23
24impl<B: Bufferable> Bufferable for Box<B> {
25    #[inline]
26    fn abandon(&mut self) {
27        self.as_mut().abandon()
28    }
29
30    #[inline]
31    fn suggested_buffer_size(&self) -> usize {
32        self.as_ref().suggested_buffer_size()
33    }
34}
35
36impl<B: Bufferable> Bufferable for &mut B {
37    #[inline]
38    fn abandon(&mut self) {
39        (**self).abandon()
40    }
41
42    #[inline]
43    fn suggested_buffer_size(&self) -> usize {
44        (**self).suggested_buffer_size()
45    }
46}
47
48impl Bufferable for std::io::Cursor<Vec<u8>> {
49    #[inline]
50    fn abandon(&mut self) {
51        self.set_position(self.get_ref().len().try_into().unwrap())
52    }
53
54    #[inline]
55    fn suggested_buffer_size(&self) -> usize {
56        0
57    }
58}
59
60impl Bufferable for std::io::Cursor<Box<[u8]>> {
61    #[inline]
62    fn abandon(&mut self) {
63        self.set_position(self.get_ref().len().try_into().unwrap())
64    }
65
66    #[inline]
67    fn suggested_buffer_size(&self) -> usize {
68        0
69    }
70}
71
72impl Bufferable for std::io::Cursor<&mut Vec<u8>> {
73    #[inline]
74    fn abandon(&mut self) {
75        self.set_position(self.get_ref().len().try_into().unwrap())
76    }
77
78    #[inline]
79    fn suggested_buffer_size(&self) -> usize {
80        0
81    }
82}
83
84impl Bufferable for std::io::Cursor<&mut [u8]> {
85    #[inline]
86    fn abandon(&mut self) {
87        self.set_position(self.get_ref().len().try_into().unwrap())
88    }
89
90    #[inline]
91    fn suggested_buffer_size(&self) -> usize {
92        0
93    }
94}
95
96impl<P> Bufferable for Pin<P>
97where
98    P: DerefMut + Unpin,
99    P::Target: Bufferable + Unpin,
100{
101    #[inline]
102    fn abandon(&mut self) {
103        Pin::get_mut(self.as_mut()).abandon()
104    }
105
106    #[inline]
107    fn suggested_buffer_size(&self) -> usize {
108        self.as_ref().suggested_buffer_size()
109    }
110}