mock_io/mock_stream/
sync.rs

1use std::{
2    io::{self, Read, Write},
3    sync::mpsc::{channel, Receiver, Sender},
4};
5
6use crate::{error::Error, sync::Handle};
7
8/// Synchronous mock IO stream
9pub struct MockStream {
10    read_half: ReadHalf,
11    write_half: WriteHalf,
12}
13
14impl MockStream {
15    /// Connects to a mock IO listener
16    pub fn connect(handle: &Handle) -> Result<Self, Error> {
17        let (stream_1, stream_2) = Self::pair();
18        handle.send(stream_2)?;
19        Ok(stream_1)
20    }
21
22    /// Creates a pair of connected mock streams
23    pub fn pair() -> (Self, Self) {
24        let (sender_1, receiver_1) = channel();
25        let (sender_2, receiver_2) = channel();
26
27        let stream_1 = Self {
28            read_half: ReadHalf {
29                receiver: receiver_1,
30                remaining: Default::default(),
31            },
32            write_half: WriteHalf { sender: sender_2 },
33        };
34
35        let stream_2 = Self {
36            read_half: ReadHalf {
37                receiver: receiver_2,
38                remaining: Default::default(),
39            },
40            write_half: WriteHalf { sender: sender_1 },
41        };
42
43        (stream_1, stream_2)
44    }
45
46    /// Splits the stream into separate read and write halves
47    pub fn split(self) -> (ReadHalf, WriteHalf) {
48        (self.read_half, self.write_half)
49    }
50}
51
52impl Read for MockStream {
53    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
54        self.read_half.read(buf)
55    }
56}
57
58impl Write for MockStream {
59    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
60        self.write_half.write(buf)
61    }
62
63    fn flush(&mut self) -> io::Result<()> {
64        self.write_half.flush()
65    }
66}
67
68/// Read half of synchronous mock IO stream
69#[derive(Debug)]
70pub struct ReadHalf {
71    receiver: Receiver<Vec<u8>>,
72    remaining: Vec<u8>,
73}
74
75impl ReadHalf {
76    fn receive(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
77        let available_space = buf.len();
78
79        if self.remaining.is_empty() {
80            self.remaining = self.receiver.recv()?;
81        }
82
83        let remaining_len = self.remaining.len();
84
85        if remaining_len > available_space {
86            buf.copy_from_slice(&self.remaining[..available_space]);
87            self.remaining = self.remaining[available_space..].to_vec();
88
89            Ok(available_space)
90        } else {
91            buf[..remaining_len].copy_from_slice(&self.remaining);
92            self.remaining = Default::default();
93
94            Ok(remaining_len)
95        }
96    }
97}
98
99impl Read for ReadHalf {
100    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
101        self.receive(buf).map_err(Into::into)
102    }
103}
104
105/// Write half of synchronous mock IO stream
106#[derive(Debug, Clone)]
107pub struct WriteHalf {
108    sender: Sender<Vec<u8>>,
109}
110
111impl WriteHalf {
112    /// Sends bytes to the stream
113    fn send(&self, bytes: &[u8]) -> Result<usize, Error> {
114        self.sender
115            .send(bytes.to_vec())
116            .map(|_| bytes.len())
117            .map_err(Into::into)
118    }
119}
120
121impl Write for WriteHalf {
122    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
123        self.send(buf).map_err(Into::into)
124    }
125
126    fn flush(&mut self) -> io::Result<()> {
127        Ok(())
128    }
129}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn check_stream_communication() {
137        let one = 1u64.to_be_bytes().to_vec();
138
139        let (mut sender, mut receiver) = MockStream::pair();
140
141        assert!(matches!(sender.write(&one), Ok(8)));
142
143        let mut buf = [0; 10];
144        assert!(matches!(receiver.read(&mut buf), Ok(8)));
145        assert_eq!(one[..], buf[..8]);
146
147        assert!(matches!(sender.write(&one), Ok(8)));
148
149        let mut buf = [0; 4];
150        assert!(matches!(receiver.read(&mut buf), Ok(4)));
151        assert_eq!(one[..4], buf[..]);
152
153        let mut buf = [0; 4];
154        assert!(matches!(receiver.read(&mut buf), Ok(4)));
155        assert_eq!(one[4..], buf[..]);
156    }
157}