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
use crate::{Bufferable, ReadLayered, Status};
use std::io::{self, IoSliceMut, Read};

/// Adapts an `&[u8]` to implement `ReadLayered`.
pub struct SliceReader<'slice> {
    slice: &'slice [u8],
}

impl<'slice> SliceReader<'slice> {
    /// Construct a new `SliceReader` which wraps `slice`.
    #[inline]
    pub fn new(slice: &'slice [u8]) -> Self {
        Self { slice }
    }
}

impl<'slice> ReadLayered for SliceReader<'slice> {
    #[inline]
    fn read_with_status(&mut self, buf: &mut [u8]) -> io::Result<(usize, Status)> {
        let size = Read::read(&mut self.slice, buf)?;
        Ok((
            size,
            if self.slice.is_empty() {
                Status::End
            } else {
                Status::active()
            },
        ))
    }

    #[inline]
    fn read_vectored_with_status(
        &mut self,
        bufs: &mut [IoSliceMut<'_>],
    ) -> io::Result<(usize, Status)> {
        let size = Read::read_vectored(&mut self.slice, bufs)?;
        Ok((
            size,
            if self.slice.is_empty() {
                Status::End
            } else {
                Status::active()
            },
        ))
    }
}

impl<'slice> Bufferable for SliceReader<'slice> {
    #[inline]
    fn abandon(&mut self) {
        self.slice = &[];
    }

    #[inline]
    fn suggested_buffer_size(&self) -> usize {
        // This is just writing values to memory, so no need to buffer.
        0
    }
}

impl<'slice> Read for SliceReader<'slice> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        Read::read(&mut self.slice, buf)
    }

    #[inline]
    fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
        Read::read_vectored(&mut self.slice, bufs)
    }

    #[cfg(can_vector)]
    #[inline]
    fn is_read_vectored(&self) -> bool {
        Read::is_read_vectored(&self.slice)
    }

    #[inline]
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        Read::read_to_end(&mut self.slice, buf)
    }

    #[inline]
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        Read::read_to_string(&mut self.slice, buf)
    }

    #[inline]
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        Read::read_exact(&mut self.slice, buf)
    }
}

#[test]
fn test_slice_read_with_status() {
    let mut reader = SliceReader::new(b"hello world!");
    let mut buf = vec![0; 5];
    assert_eq!(
        reader.read_with_status(&mut buf).unwrap(),
        (5, Status::active())
    );
    assert_eq!(buf, b"hello");
    assert_eq!(
        reader.read_with_status(&mut buf).unwrap(),
        (5, Status::active())
    );
    assert_eq!(buf, b" worl");
    assert_eq!(reader.read_with_status(&mut buf).unwrap(), (2, Status::End));
    assert_eq!(&buf[..2], b"d!");
    assert_eq!(reader.read_with_status(&mut buf).unwrap(), (0, Status::End));
}

#[test]
fn test_slice_read() {
    let mut reader = SliceReader::new(b"hello world!");
    let mut buf = vec![0; 5];
    assert_eq!(reader.read(&mut buf).unwrap(), 5);
    assert_eq!(buf, b"hello");
    assert_eq!(reader.read(&mut buf).unwrap(), 5);
    assert_eq!(buf, b" worl");
    assert_eq!(reader.read(&mut buf).unwrap(), 2);
    assert_eq!(&buf[..2], b"d!");
    assert_eq!(reader.read(&mut buf).unwrap(), 0);
}