1use std::collections::VecDeque;
35
36use bytes::{BufMut, Bytes, BytesMut};
37
38pub const MAX_VARINT: u64 = (1 << 62) - 1;
40
41pub const FRAME_DATA: u64 = 0x0;
43pub const FRAME_HEADERS: u64 = 0x1;
45pub const FRAME_CANCEL_PUSH: u64 = 0x3;
47pub const FRAME_SETTINGS: u64 = 0x4;
49pub const FRAME_PUSH_PROMISE: u64 = 0x5;
51pub const FRAME_GOAWAY: u64 = 0x7;
53pub const FRAME_MAX_PUSH_ID: u64 = 0xd;
55
56#[allow(dead_code)]
60pub const SETTINGS_QPACK_MAX_TABLE_CAPACITY: u64 = 0x1;
61#[allow(dead_code)]
65pub const SETTINGS_MAX_FIELD_SECTION_SIZE: u64 = 0x6;
66#[allow(dead_code)]
70pub const SETTINGS_QPACK_BLOCKED_STREAMS: u64 = 0x7;
71#[allow(dead_code)]
75pub const SETTINGS_ENABLE_CONNECT_PROTOCOL: u64 = 0x8;
76#[allow(dead_code)]
80pub const SETTINGS_H3_DATAGRAM: u64 = 0x33;
81
82pub type Setting = (u64, u64);
84
85#[derive(Debug, Clone, Default, PartialEq, Eq)]
91pub struct Settings {
92 entries: Vec<Setting>,
93}
94
95impl Settings {
96 #[inline]
98 pub fn new() -> Self {
99 Self::default()
100 }
101
102 #[inline]
104 pub fn insert(&mut self, id: u64, value: u64) {
105 self.entries.push((id, value));
106 }
107
108 #[inline]
110 pub fn get(&self, id: u64) -> Option<u64> {
111 self.entries
112 .iter()
113 .find_map(|(i, v)| (*i == id).then_some(*v))
114 }
115
116 #[inline]
118 pub fn iter(&self) -> impl Iterator<Item = Setting> + '_ {
119 self.entries.iter().copied()
120 }
121}
122
123#[derive(Debug, Clone, PartialEq, Eq)]
130pub enum Frame {
131 Data(Bytes),
133 Headers(Bytes),
135 Settings(Settings),
138 CancelPush(u64),
140 PushPromise { push_id: u64, field_section: Bytes },
143 Goaway(u64),
146 MaxPushId(u64),
148}
149
150impl Frame {
151 #[inline]
160 pub fn is_known(&self) -> bool {
161 matches!(
162 self,
163 Frame::Data(_)
164 | Frame::Headers(_)
165 | Frame::Settings(_)
166 | Frame::CancelPush(_)
167 | Frame::PushPromise { .. }
168 | Frame::Goaway(_)
169 | Frame::MaxPushId(_)
170 )
171 }
172
173 #[inline]
175 pub fn encode(&self, dst: &mut BytesMut) {
176 match self {
177 Frame::Data(payload) => {
178 write_varint(FRAME_DATA, dst);
179 write_varint(payload.len() as u64, dst);
180 dst.extend_from_slice(payload);
181 }
182 Frame::Headers(payload) => {
183 write_varint(FRAME_HEADERS, dst);
184 write_varint(payload.len() as u64, dst);
185 dst.extend_from_slice(payload);
186 }
187 Frame::Settings(settings) => {
188 write_varint(FRAME_SETTINGS, dst);
189 let len: usize = settings
190 .entries
191 .iter()
192 .map(|(id, value)| varint_size(*id) + varint_size(*value))
193 .sum();
194 write_varint(len as u64, dst);
195 for (id, value) in &settings.entries {
196 write_varint(*id, dst);
197 write_varint(*value, dst);
198 }
199 }
200 Frame::CancelPush(push_id) => {
201 write_varint(FRAME_CANCEL_PUSH, dst);
202 write_varint(varint_size(*push_id) as u64, dst);
203 write_varint(*push_id, dst);
204 }
205 Frame::PushPromise {
206 push_id,
207 field_section,
208 } => {
209 write_varint(FRAME_PUSH_PROMISE, dst);
210 write_varint((varint_size(*push_id) + field_section.len()) as u64, dst);
211 write_varint(*push_id, dst);
212 dst.extend_from_slice(field_section);
213 }
214 Frame::Goaway(stream_id) => {
215 write_varint(FRAME_GOAWAY, dst);
216 write_varint(varint_size(*stream_id) as u64, dst);
217 write_varint(*stream_id, dst);
218 }
219 Frame::MaxPushId(push_id) => {
220 write_varint(FRAME_MAX_PUSH_ID, dst);
221 write_varint(varint_size(*push_id) as u64, dst);
222 write_varint(*push_id, dst);
223 }
224 }
225 }
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq)]
233pub enum FrameError {
234 Frame,
238 Unexpected(u64),
242 Settings,
246}
247
248impl FrameError {
249 pub const fn h3_code(self) -> u64 {
251 use crate::h3::H3Error;
252 match self {
253 FrameError::Frame => H3Error::FrameError.code(),
254 FrameError::Unexpected(_) => H3Error::FrameUnexpected.code(),
255 FrameError::Settings => H3Error::Settings.code(),
256 }
257 }
258}
259
260#[derive(Debug, Default)]
271pub struct FrameDecoder {
272 bufs: VecDeque<Bytes>,
273 len: usize,
274}
275
276impl FrameDecoder {
277 #[inline]
279 pub fn new() -> Self {
280 Self::default()
281 }
282
283 #[inline]
285 pub fn extend(&mut self, data: Bytes) {
286 if data.is_empty() {
287 return;
288 }
289 self.len += data.len();
290 self.bufs.push_back(data);
291 }
292
293 #[inline]
295 pub fn buffered(&self) -> usize {
296 self.len
297 }
298
299 #[inline]
306 pub fn next_frame(&mut self) -> Result<Option<Frame>, FrameError> {
307 loop {
308 let Some((ty, type_len)) = self.parse_varint_at(0)? else {
309 return Ok(None);
310 };
311 if matches!(ty, 0x02 | 0x06 | 0x08 | 0x09) {
312 return Err(FrameError::Unexpected(ty));
313 }
314 let Some((len, len_len)) = self.parse_varint_at(type_len)? else {
315 return Ok(None);
316 };
317 let header_len = type_len + len_len;
318 let Some(total) = header_len.checked_add(len as usize) else {
319 return Err(FrameError::Frame);
320 };
321 if total > self.len {
322 return Ok(None);
323 }
324 if !is_known_frame_type(ty) {
325 self.advance(total);
326 continue;
327 }
328 self.advance(header_len);
329 let payload = self.take_bytes(len as usize);
330 let frame = match ty {
331 FRAME_DATA => Frame::Data(payload),
332 FRAME_HEADERS => Frame::Headers(payload),
333 FRAME_CANCEL_PUSH => Frame::CancelPush(take_varint(&payload)?),
334 FRAME_SETTINGS => Frame::Settings(parse_settings(&payload)?),
335 FRAME_PUSH_PROMISE => {
336 let Some((push_id, id_len)) = parse_varint(&payload)? else {
337 return Err(FrameError::Frame);
338 };
339 Frame::PushPromise {
340 push_id,
341 field_section: payload.slice(id_len..),
342 }
343 }
344 FRAME_GOAWAY => Frame::Goaway(take_varint(&payload)?),
345 FRAME_MAX_PUSH_ID => Frame::MaxPushId(take_varint(&payload)?),
346 _ => unreachable!("unknown types are skipped above"),
347 };
348 return Ok(Some(frame));
349 }
350 }
351
352 #[inline]
357 pub fn peek_frame_type(&self) -> Option<u64> {
358 match self.parse_varint_at(0) {
359 Ok(Some((ty, _))) => Some(ty),
360 _ => None,
361 }
362 }
363
364 #[inline]
365 fn byte_at(&self, offset: usize) -> Option<u8> {
366 let mut remaining = offset;
367 for buf in &self.bufs {
368 if remaining < buf.len() {
369 return Some(buf[remaining]);
370 }
371 remaining -= buf.len();
372 }
373 None
374 }
375
376 #[inline]
377 fn parse_varint_at(&self, offset: usize) -> Result<Option<(u64, usize)>, FrameError> {
378 if offset >= self.len {
379 return Ok(None);
380 }
381 let first = self.byte_at(offset).expect("offset < len");
382 let len = 1usize << (first >> 6);
383 if self.len < offset + len {
384 return Ok(None);
385 }
386 let mut value = u64::from(first & 0x3f);
387 for i in 1..len {
388 let b = self.byte_at(offset + i).expect("offset + offest_len < len");
389 value = (value << 8) | u64::from(b);
390 }
391 if len > 1 && value < MIN_VARINT[usize::from(first >> 6)] {
392 return Err(FrameError::Frame);
393 }
394 Ok(Some((value, len)))
395 }
396
397 #[inline]
398 fn advance(&mut self, n: usize) {
399 debug_assert!(n <= self.len);
400 let mut remaining = n;
401 while remaining > 0 {
402 let front_len = self.bufs.front().expect("advance within len").len();
403 if front_len <= remaining {
404 self.bufs.pop_front();
405 remaining -= front_len;
406 } else {
407 let mut front = self.bufs.pop_front().expect("advance within len");
408 front = front.slice(remaining..);
409 self.bufs.push_front(front);
410 remaining = 0;
411 }
412 }
413 self.len -= n;
414 }
415
416 #[inline]
417 fn take_bytes(&mut self, n: usize) -> Bytes {
418 if n == 0 {
419 return Bytes::new();
420 }
421 debug_assert!(n <= self.len);
422 if let Some(bytes) = self.bufs.pop_front_if(|front| front.len() == n) {
423 self.len -= n;
424 return bytes;
425 }
426 if let Some(mut first) = self.bufs.pop_front_if(|front| front.len() > n) {
427 let payload = first.split_to(n);
428 if !first.is_empty() {
429 self.bufs.push_front(first);
430 }
431 self.len -= n;
432 return payload;
433 }
434 let mut out = BytesMut::with_capacity(n);
436 let mut remaining = n;
437 while remaining > 0 {
438 let mut front = self.bufs.pop_front().expect("take_bytes within len");
439 if front.len() <= remaining {
440 out.extend_from_slice(&front);
441 remaining -= front.len();
442 } else {
443 let part = front.split_to(remaining);
444 out.extend_from_slice(&part);
445 self.bufs.push_front(front);
446 remaining = 0;
447 }
448 }
449 self.len -= n;
450 out.freeze()
451 }
452}
453
454#[inline]
455fn is_known_frame_type(ty: u64) -> bool {
456 matches!(
457 ty,
458 FRAME_DATA
459 | FRAME_HEADERS
460 | FRAME_CANCEL_PUSH
461 | FRAME_SETTINGS
462 | FRAME_PUSH_PROMISE
463 | FRAME_GOAWAY
464 | FRAME_MAX_PUSH_ID
465 )
466}
467
468#[inline]
471fn is_grease(v: u64) -> bool {
472 v >= 0x21 && (v - 0x21).is_multiple_of(0x1f)
473}
474
475#[inline]
476fn is_reserved_setting(id: u64) -> bool {
477 (0x02..=0x05).contains(&id)
478}
479
480#[inline]
481fn parse_settings(payload: &[u8]) -> Result<Settings, FrameError> {
482 let mut settings = Settings::new();
483 let mut rest = payload;
484 while !rest.is_empty() {
485 let Some((id, id_len)) = parse_varint(rest)? else {
486 return Err(FrameError::Frame);
487 };
488 rest = &rest[id_len..];
489 let Some((value, value_len)) = parse_varint(rest)? else {
490 return Err(FrameError::Frame);
491 };
492 rest = &rest[value_len..];
493 if is_reserved_setting(id) {
494 return Err(FrameError::Settings);
495 }
496 if settings.get(id).is_some() {
497 return Err(FrameError::Settings);
498 }
499 if !is_grease(id) {
500 settings.insert(id, value);
501 }
502 }
503 Ok(settings)
504}
505
506#[inline]
511fn take_varint(buf: &[u8]) -> Result<u64, FrameError> {
512 let Some((value, n)) = parse_varint(buf)? else {
513 return Err(FrameError::Frame);
514 };
515 if n != buf.len() {
516 return Err(FrameError::Frame);
517 }
518 Ok(value)
519}
520
521const MIN_VARINT: [u64; 4] = [0, 1 << 6, 1 << 14, 1 << 30];
525
526#[inline]
536pub(crate) fn parse_varint(buf: &[u8]) -> Result<Option<(u64, usize)>, FrameError> {
537 let Some(&first) = buf.first() else {
538 return Ok(None);
539 };
540 let len = 1usize << (first >> 6);
541 if buf.len() < len {
542 return Ok(None);
543 }
544 let mut value = u64::from(first & 0x3f);
545 for &byte in &buf[1..len] {
546 value = (value << 8) | u64::from(byte);
547 }
548 if len > 1 && value < MIN_VARINT[usize::from(first >> 6)] {
552 return Err(FrameError::Frame);
553 }
554 Ok(Some((value, len)))
555}
556
557#[inline]
559pub fn varint_size(value: u64) -> usize {
560 if value < (1 << 6) {
561 1
562 } else if value < (1 << 14) {
563 2
564 } else if value < (1 << 30) {
565 4
566 } else {
567 8
568 }
569}
570
571#[inline]
574pub fn write_varint(value: u64, dst: &mut BytesMut) {
575 debug_assert!(value <= MAX_VARINT, "varint out of range: {value:#x}");
576 if value < (1 << 6) {
577 dst.put_u8(value as u8);
578 } else if value < (1 << 14) {
579 dst.put_u16((0b01 << 14) | value as u16);
580 } else if value < (1 << 30) {
581 dst.put_u32((0b10 << 30) | value as u32);
582 } else {
583 dst.put_u64((0b11 << 62) | value);
584 }
585}
586
587#[cfg(test)]
588mod tests {
589 use super::*;
590
591 #[inline]
592 fn decode_all(decoder: &mut FrameDecoder) -> Result<Vec<Frame>, FrameError> {
593 let mut frames = Vec::new();
594 while let Some(frame) = decoder.next_frame()? {
595 frames.push(frame);
596 }
597 Ok(frames)
598 }
599
600 #[inline]
601 fn encode_frames(frames: &[Frame]) -> Bytes {
602 let mut buf = BytesMut::new();
603 for frame in frames {
604 frame.encode(&mut buf);
605 }
606 buf.freeze()
607 }
608
609 #[test]
610 fn round_trip_all_frame_types() {
611 let mut settings = Settings::new();
612 settings.insert(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 4096);
613 settings.insert(SETTINGS_MAX_FIELD_SECTION_SIZE, 100);
614 settings.insert(SETTINGS_QPACK_BLOCKED_STREAMS, 2);
615 settings.insert(0x21, 7); let frames = [
618 Frame::Data(Bytes::from_static(b"hello world")),
619 Frame::Headers(Bytes::from_static(b"\x3f\xbd\x01")),
620 Frame::Settings(settings),
621 Frame::CancelPush(7),
622 Frame::PushPromise {
623 push_id: 1,
624 field_section: Bytes::from_static(b"\x05\x00\x80"),
625 },
626 Frame::Goaway(2),
627 Frame::MaxPushId(0),
628 Frame::Data(Bytes::new()),
629 Frame::Headers(Bytes::new()),
630 ];
631 let mut decoder = FrameDecoder::new();
632 decoder.extend(encode_frames(&frames));
633 let got = decode_all(&mut decoder).expect("all frames parse");
634
635 let mut expected = frames.to_vec();
637 expected[2] = Frame::Settings(settings_without_grease());
638 assert_eq!(got, expected);
639 }
640
641 #[inline]
642 fn settings_without_grease() -> Settings {
643 let mut s = Settings::new();
644 s.insert(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 4096);
645 s.insert(SETTINGS_MAX_FIELD_SECTION_SIZE, 100);
646 s.insert(SETTINGS_QPACK_BLOCKED_STREAMS, 2);
647 s
648 }
649
650 #[test]
651 fn incremental_byte_at_a_time() {
652 let wire = encode_frames(&[
653 Frame::Headers(Bytes::from_static(b"abc")),
654 Frame::Data(Bytes::from_static(b"xy")),
655 ]);
656 let mut decoder = FrameDecoder::new();
657 let mut got = Vec::new();
658 for (i, &byte) in wire.iter().enumerate() {
659 decoder.extend(Bytes::copy_from_slice(&[byte]));
660 while let Some(frame) = decoder.next_frame().unwrap() {
661 got.push(frame);
662 }
663 if i < 4 {
664 assert!(got.is_empty(), "frame appeared early at byte {i}");
665 }
666 if i == 4 {
667 assert_eq!(got, vec![Frame::Headers(Bytes::from_static(b"abc"))]);
670 }
671 }
672 assert_eq!(
673 got,
674 vec![
675 Frame::Headers(Bytes::from_static(b"abc")),
676 Frame::Data(Bytes::from_static(b"xy")),
677 ]
678 );
679 assert_eq!(decoder.buffered(), 0);
680 }
681
682 #[test]
683 fn truncated_prefixes_are_incomplete() {
684 let mut decoder = FrameDecoder::new();
686 decoder.extend(Bytes::from_static(&[0x00]));
687 assert_eq!(decoder.next_frame().unwrap(), None);
688 decoder.extend(Bytes::from_static(&[0x05]));
690 assert_eq!(decoder.next_frame().unwrap(), None);
691 decoder.extend(Bytes::from_static(b"he"));
693 assert_eq!(decoder.next_frame().unwrap(), None);
694 decoder.extend(Bytes::from_static(b"llo"));
696 assert_eq!(
697 decode_all(&mut decoder).unwrap(),
698 vec![Frame::Data(Bytes::from_static(b"hello"))]
699 );
700
701 let mut decoder = FrameDecoder::new();
704 decoder.extend(Bytes::from_static(&[
705 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
706 ]));
707 assert_eq!(decoder.next_frame().unwrap(), None);
708 assert_eq!(decoder.buffered(), 10);
709 }
710
711 #[test]
712 fn forbidden_http2_frames() {
713 for ty in [0x02u8, 0x06, 0x08, 0x09] {
714 let mut decoder = FrameDecoder::new();
715 decoder.extend(Bytes::copy_from_slice(&[ty, 0x01, 0x00]));
716 let err = decoder.next_frame().unwrap_err();
717 assert_eq!(err, FrameError::Unexpected(u64::from(ty)));
718 assert_eq!(err.h3_code(), 0x0105);
719 }
720 }
721
722 #[test]
723 fn unknown_and_grease_frames_are_skipped() {
724 let mut wire = BytesMut::new();
727 Frame::Headers(Bytes::from_static(b"first")).encode(&mut wire);
728 write_varint(0x42, &mut wire);
729 write_varint(3, &mut wire);
730 wire.extend_from_slice(b"xyz");
731 write_varint(0x21, &mut wire);
732 write_varint(2, &mut wire);
733 wire.extend_from_slice(&[0xde, 0xad]);
734 Frame::Data(Bytes::from_static(b"last")).encode(&mut wire);
735
736 let mut decoder = FrameDecoder::new();
737 decoder.extend(wire.freeze());
738 let frames = decode_all(&mut decoder).unwrap();
739 assert_eq!(
740 frames,
741 vec![
742 Frame::Headers(Bytes::from_static(b"first")),
743 Frame::Data(Bytes::from_static(b"last")),
744 ]
745 );
746 assert_eq!(decoder.buffered(), 0);
747 }
748
749 #[test]
750 fn settings_payload_validation() {
751 let mut decoder = FrameDecoder::new();
753 decoder.extend(Bytes::from_static(&[0x04, 0x00]));
754 assert_eq!(
755 decode_all(&mut decoder).unwrap(),
756 vec![Frame::Settings(Settings::new())]
757 );
758
759 let mut wire = BytesMut::new();
761 Frame::Settings({
762 let mut s = Settings::new();
763 s.insert(0x06, 1);
764 s.insert(0x06, 2);
765 s
766 })
767 .encode(&mut wire);
768 let mut decoder = FrameDecoder::new();
769 decoder.extend(wire.freeze());
770 let err = decoder.next_frame().unwrap_err();
771 assert_eq!(err, FrameError::Settings);
772 assert_eq!(err.h3_code(), 0x0109);
773
774 for id in 0x02..=0x05 {
776 let mut wire = BytesMut::new();
777 Frame::Settings({
778 let mut s = Settings::new();
779 s.insert(id, 0);
780 s
781 })
782 .encode(&mut wire);
783 let mut decoder = FrameDecoder::new();
784 decoder.extend(wire.freeze());
785 assert_eq!(decoder.next_frame().unwrap_err(), FrameError::Settings);
786 }
787
788 let mut s = Settings::new();
791 s.insert(0x0100, 5);
792 s.insert(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
793 let mut wire = BytesMut::new();
794 Frame::Settings(s.clone()).encode(&mut wire);
795 let mut decoder = FrameDecoder::new();
796 decoder.extend(wire.freeze());
797 match decode_all(&mut decoder).unwrap()[0].clone() {
798 Frame::Settings(got) => {
799 assert_eq!(got.get(0x0100), Some(5));
800 assert_eq!(got.get(SETTINGS_ENABLE_CONNECT_PROTOCOL), Some(1));
801 }
802 other => panic!("expected Settings, got {other:?}"),
803 }
804
805 let mut decoder = FrameDecoder::new();
807 decoder.extend(Bytes::from_static(&[0x04, 0x01, 0x06]));
808 assert_eq!(decoder.next_frame().unwrap_err(), FrameError::Frame);
809 }
810
811 #[test]
812 fn fixed_value_frames_reject_bad_payloads() {
813 let mut decoder = FrameDecoder::new();
815 decoder.extend(Bytes::from_static(&[0x03, 0x00]));
816 assert_eq!(decoder.next_frame().unwrap_err(), FrameError::Frame);
817
818 let mut decoder = FrameDecoder::new();
820 decoder.extend(Bytes::from_static(&[0x03, 0x02, 0x01, 0x00]));
821 assert_eq!(decoder.next_frame().unwrap_err(), FrameError::Frame);
822
823 let mut decoder = FrameDecoder::new();
825 decoder.extend(Bytes::from_static(&[0x03, 0x02, 0x40, 0x05]));
826 assert_eq!(decoder.next_frame().unwrap_err(), FrameError::Frame);
827
828 let mut decoder = FrameDecoder::new();
830 decoder.extend(Bytes::from_static(&[0x07, 0x01, 0x05]));
831 assert_eq!(decode_all(&mut decoder).unwrap(), vec![Frame::Goaway(5)]);
832
833 let mut decoder = FrameDecoder::new();
835 decoder.extend(Bytes::from_static(&[0x40, 0x00, 0x00]));
836 assert_eq!(decoder.next_frame().unwrap_err(), FrameError::Frame);
837
838 let mut decoder = FrameDecoder::new();
840 decoder.extend(Bytes::from_static(&[0x00, 0x40, 0x00]));
841 assert_eq!(decoder.next_frame().unwrap_err(), FrameError::Frame);
842 }
843
844 #[test]
845 fn push_promise_shapes() {
846 let mut decoder = FrameDecoder::new();
848 decoder.extend(Bytes::from_static(&[0x05, 0x04, 0x01, b'a', b'b', b'c']));
849 assert_eq!(
850 decode_all(&mut decoder).unwrap(),
851 vec![Frame::PushPromise {
852 push_id: 1,
853 field_section: Bytes::from_static(b"abc"),
854 }]
855 );
856
857 let mut decoder = FrameDecoder::new();
859 decoder.extend(Bytes::from_static(&[0x05, 0x01, 0x01]));
860 assert_eq!(
861 decode_all(&mut decoder).unwrap(),
862 vec![Frame::PushPromise {
863 push_id: 1,
864 field_section: Bytes::new(),
865 }]
866 );
867
868 let mut decoder = FrameDecoder::new();
870 decoder.extend(Bytes::from_static(&[0x05, 0x00]));
871 assert_eq!(decoder.next_frame().unwrap_err(), FrameError::Frame);
872 }
873
874 #[test]
875 fn varint_edge_encodings() {
876 for value in [
879 (1 << 6) - 1,
880 1 << 6,
881 (1 << 14) - 1,
882 1 << 14,
883 (1 << 30) - 1,
884 1 << 30,
885 MAX_VARINT,
886 ] {
887 let mut wire = BytesMut::new();
888 write_varint(value, &mut wire);
889 assert_eq!(wire.len(), varint_size(value));
890 let (got, n) = parse_varint(&wire).unwrap().unwrap();
891 assert_eq!(got, value);
892 assert_eq!(n, wire.len());
893 }
894
895 assert_eq!(parse_varint(&[0x40, 0x00]), Err(FrameError::Frame)); assert_eq!(
898 parse_varint(&[0x80, 0x00, 0x00, 0x40]),
899 Err(FrameError::Frame)
900 ); assert_eq!(parse_varint(&[0x40, 0x40]), Ok(Some((64, 2))));
902 assert_eq!(parse_varint(&[0x40]), Ok(None));
904 assert_eq!(parse_varint(&[]), Ok(None));
905 }
906
907 #[test]
908 fn clean_eof_with_truncated_frame_is_detectable() {
909 let mut decoder = FrameDecoder::new();
910 decoder.extend(Bytes::from_static(&[0x01, 0x05, b'a', b'b']));
911 assert_eq!(decoder.next_frame().unwrap(), None);
912 assert_eq!(decoder.buffered(), 4);
914 }
915}