From 86249001db3a19ffab6147cfb1fe3bd3ff3a8d4a Mon Sep 17 00:00:00 2001 From: DatCaptainHorse Date: Fri, 2 Oct 2026 16:53:30 +0300 Subject: [PATCH] feat: let a frame reader hand back what it read past a frame The end that reads the first frame of an attach stream to learn whom the connection is for then forwards the rest untouched, and what arrived behind that frame in the same read belongs to the stream. Co-Authored-By: Claude Sonnet 5.5 --- crates/nesprotocol/src/attach.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/crates/nesprotocol/src/attach.rs b/crates/nesprotocol/src/attach.rs index 199d7a06..ee45d049 100644 --- a/crates/nesprotocol/src/attach.rs +++ b/crates/nesprotocol/src/attach.rs @@ -135,6 +135,15 @@ impl FrameReader { self.buf.extend_from_slice(bytes); } + /// What has arrived and is not yet a frame, handing the reader up. + /// + /// For the end that reads the first frame to learn whom a connection is for + /// and then forwards the rest untouched: whatever came in behind that frame + /// in the same read belongs to the stream, and is not to be lost. + pub fn into_remaining(self) -> Vec { + self.buf + } + /// The next whole frame, if one has arrived. /// /// `Ok(None)` is "not yet". After an error the reader is poisoned in the @@ -256,6 +265,19 @@ mod tests { } } + /// The first frame is read to learn who is calling; whatever came in behind it + /// in the same read is the stream's, and is not dropped. + #[test] + fn what_arrived_behind_a_frame_is_handed_on() { + let mut reader = FrameReader::new(); + let mut wire = Frame::Hello("a".into()).encode().unwrap(); + wire.extend(Frame::Data(b"prompt$ ".to_vec()).encode().unwrap()); + reader.push(&wire); + assert_eq!(reader.next_frame().unwrap(), Some(Frame::Hello("a".into()))); + let rest = reader.into_remaining(); + assert_eq!(rest, Frame::Data(b"prompt$ ".to_vec()).encode().unwrap()); + } + #[test] fn two_frames_in_one_read_come_out_as_two() { let mut reader = FrameReader::new();