1use bytes::Bytes;
2use snafu::Snafu;
3use tracing::trace;
4
5use crate::buf::ReadIoBuffer;
6
7mod length_delimited;
8pub use self::length_delimited::LengthDelimitedFramer;
9
10mod newline;
11pub use self::newline::NewlineFramer;
12
13#[derive(Debug, Snafu, Eq, PartialEq)]
15#[snafu(context(suffix(false)))]
16pub enum FramingError {
17 #[snafu(display("invalid frame (frame length: {}, {})", frame_len, reason))]
25 InvalidFrame { frame_len: usize, reason: &'static str },
26
27 #[snafu(display(
32 "partial frame after EOF (needed {} bytes, but only {} bytes remaining)",
33 needed,
34 remaining
35 ))]
36 PartialFrame { needed: usize, remaining: usize },
37}
38
39pub trait Framer {
41 fn next_frame<B: ReadIoBuffer>(&mut self, buf: &mut B, is_eof: bool) -> Result<Option<Bytes>, FramingError>;
53}
54
55pub struct NestedFramer<Inner, Outer> {
61 inner: Inner,
62 outer: Outer,
63 current_outer_frame: Option<Bytes>,
64 completed_outer_frames: usize,
65 retain_outer_frames: bool,
66 retained_outer_frames: Vec<Bytes>,
67}
68
69impl<Inner, Outer> NestedFramer<Inner, Outer> {
70 pub fn new(inner: Inner, outer: Outer) -> Self {
72 Self {
73 inner,
74 outer,
75 current_outer_frame: None,
76 completed_outer_frames: 0,
77 retain_outer_frames: false,
78 retained_outer_frames: Vec::new(),
79 }
80 }
81
82 pub fn take_completed_outer_frames(&mut self) -> usize {
84 let completed = self.completed_outer_frames;
85 self.completed_outer_frames = 0;
86 completed
87 }
88
89 pub fn set_retain_outer_frames(&mut self, retain: bool) {
100 self.retain_outer_frames = retain;
101 if !retain {
102 self.retained_outer_frames.clear();
103 }
104 }
105
106 pub fn drain_outer_frames(&mut self) -> std::vec::Drain<'_, Bytes> {
108 self.retained_outer_frames.drain(..)
109 }
110}
111
112impl<Inner, Outer> Framer for NestedFramer<Inner, Outer>
113where
114 Inner: Framer,
115 Outer: Framer,
116{
117 fn next_frame<B: ReadIoBuffer>(&mut self, buf: &mut B, is_eof: bool) -> Result<Option<Bytes>, FramingError> {
118 loop {
119 let outer_frame = match self.current_outer_frame.as_mut() {
121 Some(frame) => {
122 trace!(
123 buf_len = buf.remaining(),
124 frame_len = frame.len(),
125 "Using existing outer frame."
126 );
127
128 frame
129 }
130 None => {
131 trace!(buf_len = buf.remaining(), "No existing outer frame.");
132
133 match self.outer.next_frame(buf, is_eof)? {
134 Some(frame) => {
135 trace!(
136 buf_len = buf.remaining(),
137 frame_len = frame.len(),
138 ?frame,
139 "Extracted outer frame."
140 );
141
142 if self.retain_outer_frames {
143 self.retained_outer_frames.push(frame.clone());
144 }
145
146 self.current_outer_frame.get_or_insert(frame)
147 }
148
149 None => return Ok(None),
151 }
152 }
153 };
154
155 match self.inner.next_frame(outer_frame, true)? {
157 Some(frame) => {
158 let completed_outer_frame = outer_frame.is_empty();
159
160 trace!(
161 buf_len = buf.remaining(),
162 outer_frame_len = outer_frame.len(),
163 inner_frame_len = frame.len(),
164 "Extracted inner frame."
165 );
166
167 if completed_outer_frame {
168 self.current_outer_frame = None;
169 self.completed_outer_frames += 1;
170 }
171
172 return Ok(Some(frame));
173 }
174 None => {
175 trace!(
178 buf_len = buf.remaining(),
179 outer_frame_len = outer_frame.len(),
180 "Couldn't extract inner frame from existing outer frame."
181 );
182
183 if outer_frame.is_empty() {
184 self.current_outer_frame = None;
185 self.completed_outer_frames += 1;
186 if buf.remaining() != 0 {
187 continue;
188 }
189 }
190
191 return Ok(None);
192 }
193 }
194 }
195 }
196}
197
198pub struct Framed<'a, F, B> {
200 framer: &'a mut F,
201 buffer: &'a mut B,
202 is_eof: bool,
203}
204
205impl<F, B> Iterator for Framed<'_, F, B>
206where
207 F: Framer,
208 B: ReadIoBuffer,
209{
210 type Item = Result<Bytes, FramingError>;
211
212 fn next(&mut self) -> Option<Self::Item> {
213 self.framer.next_frame(self.buffer, self.is_eof).transpose()
214 }
215}
216
217pub trait FramerExt {
219 fn framed<'a, F>(&'a mut self, framer: &'a mut F, is_eof: bool) -> Framed<'a, F, Self>
224 where
225 Self: ReadIoBuffer + Sized,
226 F: Framer;
227}
228
229impl<B> FramerExt for B
230where
231 B: ReadIoBuffer,
232{
233 fn framed<'a, F>(&'a mut self, framer: &'a mut F, is_eof: bool) -> Framed<'a, F, Self> {
234 Framed {
235 framer,
236 buffer: self,
237 is_eof,
238 }
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use std::collections::VecDeque;
245
246 use super::{Framer as _, LengthDelimitedFramer, NestedFramer, NewlineFramer};
247
248 #[test]
249 fn nested_framer_single_outer_multiple_inner() {
250 let input_frames = &[b"frame1", b"frame2", b"frame3"];
251
252 let mut framer = NestedFramer::new(NewlineFramer::default(), LengthDelimitedFramer);
255
256 let mut inner_frames = Vec::new();
258
259 for inner_frame_data in input_frames {
260 inner_frames.extend_from_slice(&inner_frame_data[..]);
261 inner_frames.push(b'\n');
262 }
263
264 let mut buf = VecDeque::new();
265 buf.extend(&(inner_frames.len() as u32).to_le_bytes());
266 buf.extend(inner_frames);
267
268 for input_frame in input_frames {
270 let frame = framer
271 .next_frame(&mut buf, false)
272 .expect("should not fail to read from payload")
273 .expect("should not fail to extract frame from payload");
274 assert_eq!(&frame[..], &input_frame[..]);
275 }
276
277 let maybe_frame = framer
278 .next_frame(&mut buf, false)
279 .expect("should not fail to read from payload");
280 assert!(maybe_frame.is_none());
281
282 assert!(buf.is_empty());
284 }
285
286 #[test]
287 fn nested_framer_multiple_outer_single_inner() {
288 let input_frames = &[b"frame1", b"frame2", b"frame3"];
289
290 let mut framer = NestedFramer::new(NewlineFramer::default(), LengthDelimitedFramer);
293
294 let mut buf = VecDeque::new();
296
297 for inner_frame_data in input_frames {
298 let mut inner_frame = Vec::new();
299 inner_frame.extend_from_slice(&inner_frame_data[..]);
300 inner_frame.push(b'\n');
301
302 buf.extend(&(inner_frame.len() as u32).to_le_bytes());
303 buf.extend(inner_frame);
304 }
305
306 for input_frame in input_frames {
308 let frame = framer
309 .next_frame(&mut buf, false)
310 .expect("should not fail to read from payload")
311 .expect("should not fail to extract frame from payload");
312 assert_eq!(&frame[..], &input_frame[..]);
313 }
314
315 let maybe_frame = framer
316 .next_frame(&mut buf, false)
317 .expect("should not fail to read from payload");
318 assert!(maybe_frame.is_none());
319
320 assert!(buf.is_empty());
322 }
323
324 #[test]
325 fn nested_framer_tracks_completed_outer_frames() {
326 let input_frames = &[b"frame1", b"frame2", b"frame3"];
327 let mut framer = NestedFramer::new(NewlineFramer::default(), LengthDelimitedFramer);
328 let mut buf = VecDeque::new();
329
330 for inner_frame_data in input_frames {
331 let mut inner_frame = Vec::new();
332 inner_frame.extend_from_slice(&inner_frame_data[..]);
333 inner_frame.push(b'\n');
334
335 buf.extend(&(inner_frame.len() as u32).to_le_bytes());
336 buf.extend(inner_frame);
337 }
338
339 for input_frame in input_frames {
340 let frame = framer
341 .next_frame(&mut buf, false)
342 .expect("should not fail to read from payload")
343 .expect("should extract frame from payload");
344 assert_eq!(&frame[..], &input_frame[..]);
345 assert_eq!(framer.take_completed_outer_frames(), 1);
346 }
347
348 assert!(buf.is_empty());
349 assert_eq!(framer.take_completed_outer_frames(), 0);
350 }
351
352 #[test]
353 fn nested_framer_retains_outer_frames_only_when_enabled() {
354 let outer_payloads: &[&[u8]] = &[b"frame1\nframe2\n", b"frame3\n"];
355 let mut buf = VecDeque::new();
356 for payload in outer_payloads {
357 buf.extend(&(payload.len() as u32).to_le_bytes());
358 buf.extend(payload.iter());
359 }
360 let mut framer = NestedFramer::new(NewlineFramer::default(), LengthDelimitedFramer);
361
362 let first = framer.next_frame(&mut buf, false).unwrap().unwrap();
363 assert_eq!(&first[..], b"frame1");
364 assert_eq!(framer.drain_outer_frames().count(), 0);
365
366 framer.set_retain_outer_frames(true);
367 let second = framer.next_frame(&mut buf, false).unwrap().unwrap();
368 assert_eq!(&second[..], b"frame2");
369 assert_eq!(framer.drain_outer_frames().count(), 0);
370
371 let third = framer.next_frame(&mut buf, false).unwrap().unwrap();
372 assert_eq!(&third[..], b"frame3");
373 let retained = framer.drain_outer_frames().collect::<Vec<_>>();
374 assert_eq!(retained.len(), 1);
375 assert_eq!(&retained[0][..], outer_payloads[1]);
376 assert_eq!(framer.drain_outer_frames().count(), 0);
377
378 buf.extend(&(outer_payloads[0].len() as u32).to_le_bytes());
379 buf.extend(outer_payloads[0].iter());
380 let _ = framer.next_frame(&mut buf, false).unwrap().unwrap();
381 framer.set_retain_outer_frames(false);
382 assert_eq!(framer.drain_outer_frames().count(), 0);
383 }
384
385 #[test]
386 fn nested_framer_waits_to_complete_outer_frame_until_last_inner_frame() {
387 let mut framer = NestedFramer::new(NewlineFramer::default(), LengthDelimitedFramer);
388 let mut inner_frames = Vec::new();
389 inner_frames.extend_from_slice(b"frame1\nframe2\n");
390
391 let mut buf = VecDeque::new();
392 buf.extend(&(inner_frames.len() as u32).to_le_bytes());
393 buf.extend(inner_frames);
394
395 let first_frame = framer
396 .next_frame(&mut buf, false)
397 .expect("should not fail to read from payload")
398 .expect("should extract first frame from payload");
399 assert_eq!(&first_frame[..], b"frame1");
400 assert_eq!(framer.take_completed_outer_frames(), 0);
401
402 let second_frame = framer
403 .next_frame(&mut buf, false)
404 .expect("should not fail to read from payload")
405 .expect("should extract second frame from payload");
406 assert_eq!(&second_frame[..], b"frame2");
407 assert_eq!(framer.take_completed_outer_frames(), 1);
408 }
409
410 #[test]
411 fn nested_framer_multiple_outer_multiple_inner() {
412 let input_frames = &[b"frame1", b"frame2", b"frame3", b"frame4", b"frame5", b"frame6"];
413
414 let mut framer = NestedFramer::new(NewlineFramer::default(), LengthDelimitedFramer);
417
418 let mut buf = VecDeque::new();
420
421 for inner_frame_data in input_frames.chunks(2) {
422 let mut inner_frames = Vec::new();
423 inner_frames.extend_from_slice(&inner_frame_data[0][..]);
424 inner_frames.push(b'\n');
425 inner_frames.extend_from_slice(&inner_frame_data[1][..]);
426 inner_frames.push(b'\n');
427
428 buf.extend(&(inner_frames.len() as u32).to_le_bytes());
429 buf.extend(inner_frames);
430 }
431
432 for input_frame in input_frames {
434 let frame = framer
435 .next_frame(&mut buf, false)
436 .expect("should not fail to read from payload")
437 .expect("should not fail to extract frame from payload");
438 assert_eq!(&frame[..], &input_frame[..]);
439 }
440
441 let maybe_frame = framer
442 .next_frame(&mut buf, false)
443 .expect("should not fail to read from payload");
444 assert!(maybe_frame.is_none());
445
446 assert!(buf.is_empty());
448 }
449}