1use core::iter::FusedIterator;
4
5use super::error::KcpSegmentsParseError;
6use super::segment::KcpSegment;
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub struct KcpSegments<'a> {
11 bytes: &'a [u8],
12}
13
14impl<'a> KcpSegments<'a> {
15 pub fn parse(bytes: &'a [u8]) -> Result<Self, KcpSegmentsParseError> {
20 if bytes.is_empty() {
21 return Err(KcpSegmentsParseError::EmptySequence);
22 }
23
24 for segment in KcpSegmentIter::new(bytes) {
25 segment?;
26 }
27 Ok(Self { bytes })
28 }
29
30 pub const fn as_bytes(self) -> &'a [u8] {
32 self.bytes
33 }
34
35 pub const fn iter(self) -> KcpSegmentIter<'a> {
37 KcpSegmentIter::new(self.bytes)
38 }
39}
40
41#[derive(Clone, Debug)]
46pub struct KcpSegmentIter<'a> {
47 remaining: &'a [u8],
48 offset: usize,
49 exhausted: bool,
50}
51
52impl<'a> KcpSegmentIter<'a> {
53 pub const fn new(bytes: &'a [u8]) -> Self {
55 Self {
56 remaining: bytes,
57 offset: 0,
58 exhausted: false,
59 }
60 }
61}
62
63impl<'a> Iterator for KcpSegmentIter<'a> {
64 type Item = Result<KcpSegment<'a>, KcpSegmentsParseError>;
65
66 fn next(&mut self) -> Option<Self::Item> {
67 if self.exhausted || self.remaining.is_empty() {
68 self.exhausted = true;
69 return None;
70 }
71
72 match KcpSegment::parse(self.remaining) {
73 Ok((segment, suffix)) => {
74 let length = segment.as_bytes().len();
75 self.offset += length;
76 self.remaining = suffix;
77 Some(Ok(segment))
78 }
79 Err(error) => self.fail(KcpSegmentsParseError::Segment {
80 offset: self.offset,
81 error,
82 }),
83 }
84 }
85}
86
87impl FusedIterator for KcpSegmentIter<'_> {}
88
89impl<'a> KcpSegmentIter<'a> {
90 fn fail(
91 &mut self,
92 error: KcpSegmentsParseError,
93 ) -> Option<Result<KcpSegment<'a>, KcpSegmentsParseError>> {
94 self.remaining = &[];
95 self.exhausted = true;
96 Some(Err(error))
97 }
98}