sliceable_ring_buffer/
io.rs

1use super::SliceRingBuffer;
2use std::{
3    io::{self, Read, Write},
4    ptr,
5};
6
7impl Read for SliceRingBuffer<u8> {
8    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
9        let available_data = self.as_slice();
10        let len_to_copy = available_data.len().min(buf.len());
11        if len_to_copy == 0 {
12            return Ok(0);
13        }
14        buf[..len_to_copy].copy_from_slice(&available_data[..len_to_copy]);
15        self.move_head(len_to_copy.cast_signed());
16        Ok(len_to_copy)
17    }
18}
19
20impl Write for SliceRingBuffer<u8> {
21    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
22        self.reserve(buf.len());
23        let uninit_slice = self.uninit_slice();
24        unsafe {
25            let dst_ptr = uninit_slice.as_mut_ptr().cast::<u8>();
26            ptr::copy_nonoverlapping(buf.as_ptr(), dst_ptr, buf.len());
27        }
28        self.move_tail(buf.len().cast_signed());
29        Ok(buf.len())
30    }
31
32    fn flush(&mut self) -> io::Result<()> { Ok(()) }
33}
34
35#[cfg(all(test, feature = "io"))]
36mod tests {
37    use crate::SliceRingBuffer;
38    use std::io::{self, Read, Write};
39
40    #[test]
41    fn test_read() {
42        let mut source = SliceRingBuffer::from(b"hello".to_vec());
43        let mut dest = [0u8; 3];
44
45        // 读满 dest
46        let bytes_read = source.read(&mut dest).unwrap();
47        assert_eq!(bytes_read, 3);
48        assert_eq!(&dest, b"hel");
49        assert_eq!(source.as_slice(), b"lo"); // 应该消耗掉了 "hel"
50
51        // 读剩余的
52        let bytes_read = source.read(&mut dest).unwrap();
53        assert_eq!(bytes_read, 2);
54        assert_eq!(&dest[..2], b"lo");
55        assert!(source.is_empty());
56
57        // 再次读取应该返回 Ok(0)
58        let bytes_read = source.read(&mut dest).unwrap();
59        assert_eq!(bytes_read, 0);
60    }
61
62    #[test]
63    fn test_write() {
64        let mut buf = SliceRingBuffer::<u8>::new();
65        let bytes_written = buf.write(b"world").unwrap();
66        assert_eq!(bytes_written, 5);
67        assert_eq!(buf.as_slice(), b"world");
68    }
69
70    #[test]
71    fn test_io_copy() {
72        let mut source = SliceRingBuffer::from(b"copy me".to_vec());
73        let mut dest = SliceRingBuffer::<u8>::new();
74
75        let bytes_copied = io::copy(&mut source, &mut dest).unwrap();
76        assert_eq!(bytes_copied, 7);
77        assert!(source.is_empty());
78        assert_eq!(dest.as_slice(), b"copy me");
79    }
80}