1use crate::error::{Error, ErrorKind, Result};
22use crate::Version;
23use std::io::{Read, Write};
24
25#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Copy, Clone)]
27pub enum Direction {
28 Unknown,
29 ToServer,
30 ToClient,
31}
32
33#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
35pub struct Data {
36 direction: Direction,
37 data: Vec<u8>,
38}
39
40#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
42pub struct Gap {
43 direction: Direction,
44 gap: usize,
45}
46
47#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
49pub enum Call {
50 Parse(Data),
52 Gap(Gap),
54}
55
56pub struct Reader<R: Read> {
58 inner: R,
59}
60
61impl<R: Read> Reader<R> {
62 pub fn new(inner: R) -> Result<Self> {
67 let mut reader = Reader { inner };
68 let expected_version = crate::version();
69 let actual_version: Version = rmp_serde::from_read(&mut reader.inner)?;
70 if expected_version != actual_version {
71 return Err(Error::new(ErrorKind::VersionMismatch((
72 expected_version,
73 actual_version,
74 ))));
75 }
76 Ok(reader)
77 }
78}
79
80impl<R: Read> std::iter::Iterator for Reader<R> {
81 type Item = Call;
82
83 fn next(&mut self) -> Option<Self::Item> {
84 rmp_serde::from_read(&mut self.inner).ok()
85 }
86}
87
88pub struct Writer<W: Write> {
90 inner: W,
91}
92
93impl<W: Write> Writer<W> {
94 pub fn new(inner: W) -> Result<Self> {
96 let mut writer = Writer { inner };
97 writer.version()?;
98 Ok(writer)
99 }
100
101 fn version(&mut self) -> Result<()> {
103 let bytes = rmp_serde::to_vec(&crate::version())?;
104 self.inner.write_all(&bytes)?;
105 Ok(())
106 }
107
108 pub fn parse(&mut self, direction: Direction, data: &[u8]) -> Result<()> {
110 let call = Call::Parse(Data {
111 direction,
112 data: data.to_vec(),
113 });
114 let bytes = rmp_serde::to_vec(&call)?;
115 self.inner.write_all(&bytes)?;
116 Ok(())
117 }
118
119 pub fn gap(&mut self, direction: Direction, gap: usize) -> Result<()> {
121 let call = Call::Gap(Gap { direction, gap });
122 let bytes = rmp_serde::to_vec(&call)?;
123 self.inner.write_all(&bytes)?;
124 Ok(())
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_read_write() {
134 let data = b"GET /index.php HTTP/1.1\r\n\r\n";
135 let gap = 10;
136
137 let mut buffer = Vec::new();
138 let mut writer = Writer::new(&mut buffer).expect("failed to create writer");
139 writer.parse(Direction::ToServer, data).unwrap();
140 writer.gap(Direction::ToServer, gap).unwrap();
141
142 let buffer = std::io::Cursor::new(buffer);
143 let reader = Reader::new(buffer).expect("failed to create reader");
144 let result: Vec<Call> = reader.collect();
145 let expected: Vec<Call> = vec![
146 Call::Parse(Data {
147 direction: Direction::ToServer,
148 data: data.to_vec(),
149 }),
150 Call::Gap(Gap {
151 direction: Direction::ToServer,
152 gap,
153 }),
154 ];
155 assert_eq!(expected, result);
156 }
157
158 #[should_panic(expected = "VersionMismatch")]
159 #[test]
160 fn test_version_mismatch() {
161 let wrong_version = crate::version() + 1;
163 let bytes = rmp_serde::to_vec(&wrong_version).unwrap();
164 let buffer = std::io::Cursor::new(bytes);
165 let _ = Reader::new(buffer).unwrap();
166 }
167
168 #[test]
169 fn test_corrupt_bytes() {
170 let data = b"GET /index.php HTTP/1.1\r\n\r\n";
171 let gap = 10;
172
173 let mut buffer = Vec::new();
174 let mut writer = Writer::new(&mut buffer).expect("failed to create writer");
175 writer.parse(Direction::ToServer, data).unwrap();
176 writer.gap(Direction::ToServer, gap).unwrap();
177
178 let buffer = std::io::Cursor::new(&buffer[..buffer.len() - 1]);
180 let reader = Reader::new(buffer).expect("failed to create reader");
181
182 assert_eq!(reader.count(), 1);
184 }
185}