1use std::io::{Read, Seek};
2pub(crate) struct Inner<T> {
3 buf: T,
4 len: Option<u64>,
5}
6impl<T> Inner<T> {
7 pub(crate) fn new(buf: T) -> Self {
8 Self { buf, len: None }
9 }
10 pub(crate) fn inner(self) -> T {
11 self.buf
12 }
13 #[allow(dead_code)]
14 pub fn get(&self) -> &T {
15 &self.buf
16 }
17}
18
19impl<T: Read> Read for Inner<T> {
20 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
21 self.buf.read(buf)
22 }
23}
24
25impl<T: Seek> Seek for Inner<T> {
26 fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
27 self.buf.seek(pos)
28 }
29}
30
31impl<T: Seek> Inner<T> {
32 pub(crate) fn len(&mut self) -> std::io::Result<u64> {
33 if let Some(len) = self.len {
34 Ok(len)
35 } else {
36 let pos = self.buf.stream_position()?;
37 let len = self.buf.seek(std::io::SeekFrom::End(0))?;
38 self.buf.seek(std::io::SeekFrom::Start(pos))?;
39 self.len = Some(len);
40 Ok(len)
41 }
42 }
43}
44#[cfg(feature = "async")]
45impl<T: tokio::io::AsyncRead + Unpin> tokio::io::AsyncRead for Inner<T> {
46 fn poll_read(
47 self: std::pin::Pin<&mut Self>,
48 cx: &mut std::task::Context<'_>,
49 buf: &mut tokio::io::ReadBuf<'_>,
50 ) -> std::task::Poll<std::io::Result<()>> {
51 tokio::io::AsyncRead::poll_read(std::pin::pin!(&mut self.get_mut().buf), cx, buf)
52 }
53}