1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use std::{
    io::{Read, Seek},
    ops::Deref,
};

/// A bytes wrapper and implements trait [`Read`][std::io::Read]
/// # Usage
/// ```
/// use multi_readers::BytesReader;
/// use std::io::Read;
/// let bytes = b"hello world";
/// let mut reader = BytesReader::new(bytes.to_vec());
/// let mut buf = [0; 6];
/// let size = reader.read(&mut buf).unwrap();
/// assert_eq!(&buf[..size], b"hello ");
/// let size = reader.read(&mut buf).unwrap();
/// assert_eq!(&buf[..size], b"world");
/// ```
///
pub struct BytesReader {
    pub(crate) buf: Vec<u8>,
    pub(crate) pos: usize,
}
impl BytesReader {
    /// Create a new `BytesReader` with bytes
    pub fn new(buf: Vec<u8>) -> BytesReader {
        Self { buf, pos: 0 }
    }
    pub(crate) fn as_slice_reader(&self) -> SliceReader<'_> {
        SliceReader {
            buf: &self.buf,
            pos: self.pos,
        }
    }
}
impl Read for BytesReader {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        let mut slice_reader = self.as_slice_reader();
        let len = std::io::Read::read(&mut slice_reader, buf)?;
        self.pos = slice_reader.pos;
        Ok(len)
    }
}
impl Seek for BytesReader {
    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
        let mut slice_reader = self.as_slice_reader();
        let len = slice_reader.seek(pos)?;
        self.pos = slice_reader.pos;
        Ok(len)
    }
}

/// A slice wrapper and implements trait [`Read`][std::io::Read]
/// # Usage
/// ```
/// use multi_readers::SliceReader;
/// use std::io::Read;
/// let slice = b"hello world";
/// let mut reader = SliceReader::new(slice);
/// let mut buf = [0; 6];
/// let size = reader.read(&mut buf).unwrap();
/// assert_eq!(&buf[..size], b"hello ");
/// let size = reader.read(&mut buf).unwrap();
/// assert_eq!(&buf[..size], b"world");
/// ```
///
pub struct SliceReader<'a> {
    pub(crate) buf: &'a [u8],
    pub(crate) pos: usize,
}

impl<'a> Deref for SliceReader<'a> {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        self.buf
    }
}

impl<'a> Seek for SliceReader<'a> {
    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
        match pos {
            std::io::SeekFrom::Start(s) => {
                let pos = s.min(self.buf.len() as u64);
                self.pos = pos as usize;
                Ok(pos)
            }
            std::io::SeekFrom::End(e) => {
                let pos = if e >= 0 {
                    self.buf.len() as u64
                } else {
                    let pos = self.buf.len() as i64 + e;
                    0.max(pos) as u64
                };
                self.pos = pos as usize;
                Ok(pos)
            }
            std::io::SeekFrom::Current(c) => {
                let len = self.buf.len() as i64;
                let pos = 0.max(len + c).min(len) as u64;
                self.pos = pos as usize;
                Ok(pos)
            }
        }
    }
}

impl<'a> SliceReader<'a> {
    /// Create a new `SliceReader` with slice
    pub fn new(slice: &'a [u8]) -> SliceReader {
        Self { buf: slice, pos: 0 }
    }
}
impl<'a> From<&'a str> for SliceReader<'a> {
    fn from(value: &'a str) -> Self {
        Self::new(value.as_bytes())
    }
}

impl<'a> From<&'a [u8]> for SliceReader<'a> {
    fn from(value: &'a [u8]) -> Self {
        Self::new(value)
    }
}
impl<'a> Read for SliceReader<'a> {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        let remain = self.buf.len() - self.pos;
        if remain == 0 {
            return Ok(0);
        }
        if buf.len() >= remain {
            buf[..remain].copy_from_slice(&self.buf[self.pos..]);
            self.pos = self.buf.len();
            Ok(remain)
        } else {
            buf.copy_from_slice(&self.buf[self.pos..self.pos + buf.len()]);
            self.pos += buf.len();
            Ok(buf.len())
        }
    }
}