stuffr_core/source/
reader.rs1use std::io::Read;
2
3use super::{SeekRead, Source, SourceCaps};
4use crate::error::Result;
5
6pub struct ReaderSource {
10 inner: Box<dyn Read + Send>,
11}
12
13impl ReaderSource {
14 pub fn new<R: Read + Send + 'static>(inner: R) -> Self {
15 Self {
16 inner: Box::new(inner),
17 }
18 }
19}
20
21impl Read for ReaderSource {
22 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
23 self.inner.read(buf)
24 }
25}
26
27impl Source for ReaderSource {
28 fn caps(&self) -> SourceCaps {
29 SourceCaps {
30 seekable: false,
31 len: None,
32 }
33 }
34
35 fn as_seek(&mut self) -> Option<&mut dyn SeekRead> {
36 None
37 }
38}
39
40pub struct PeekSource {
45 inner: Box<dyn Source>,
46 prefix: Vec<u8>,
47 pos: usize,
48}
49
50impl PeekSource {
51 pub fn fill(mut inner: Box<dyn Source>, n: usize) -> Result<Self> {
54 let mut prefix = vec![0u8; n];
55 let mut filled = 0;
56 while filled < n {
57 match inner.read(&mut prefix[filled..])? {
58 0 => break,
59 k => filled += k,
60 }
61 }
62 prefix.truncate(filled);
63 Ok(Self {
64 inner,
65 prefix,
66 pos: 0,
67 })
68 }
69
70 pub fn prefix(&self) -> &[u8] {
71 &self.prefix
72 }
73}
74
75impl Read for PeekSource {
76 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
77 if self.pos < self.prefix.len() {
78 let n = (self.prefix.len() - self.pos).min(buf.len());
79 buf[..n].copy_from_slice(&self.prefix[self.pos..self.pos + n]);
80 self.pos += n;
81 return Ok(n);
82 }
83 self.inner.read(buf)
84 }
85}
86
87impl Source for PeekSource {
88 fn caps(&self) -> SourceCaps {
89 SourceCaps {
91 seekable: false,
92 len: None,
93 }
94 }
95
96 fn as_seek(&mut self) -> Option<&mut dyn SeekRead> {
97 None
98 }
99}