1mod ip;
5
6pub mod v1;
7pub mod v2;
8
9pub trait PartialResult {
12 fn is_complete(&self) -> bool {
16 !self.is_incomplete()
17 }
18
19 fn is_incomplete(&self) -> bool;
23}
24
25impl<'a, T, E: PartialResult> PartialResult for Result<T, E> {
26 fn is_incomplete(&self) -> bool {
27 match self {
28 Ok(_) => false,
29 Err(error) => error.is_incomplete(),
30 }
31 }
32}
33
34impl<'a> PartialResult for v1::ParseError {
35 fn is_incomplete(&self) -> bool {
36 matches!(
37 self,
38 v1::ParseError::Partial
39 | v1::ParseError::MissingPrefix
40 | v1::ParseError::MissingProtocol
41 | v1::ParseError::MissingSourceAddress
42 | v1::ParseError::MissingDestinationAddress
43 | v1::ParseError::MissingSourcePort
44 | v1::ParseError::MissingDestinationPort
45 | v1::ParseError::MissingNewLine
46 )
47 }
48}
49
50impl<'a> PartialResult for v1::BinaryParseError {
51 fn is_incomplete(&self) -> bool {
52 match self {
53 v1::BinaryParseError::Parse(error) => error.is_incomplete(),
54 _ => false,
55 }
56 }
57}
58
59impl<'a> PartialResult for v2::ParseError {
60 fn is_incomplete(&self) -> bool {
61 matches!(
62 self,
63 v2::ParseError::Incomplete(..) | v2::ParseError::Partial(..)
64 )
65 }
66}
67
68#[derive(Debug, PartialEq)]
81#[must_use = "this `HeaderResult` may contain a V1 or V2 `Err` variant, which should be handled"]
82pub enum HeaderResult<'a> {
83 V1(Result<v1::Header<'a>, v1::BinaryParseError>),
84 V2(Result<v2::Header<'a>, v2::ParseError>),
85}
86
87impl<'a> From<Result<v1::Header<'a>, v1::BinaryParseError>> for HeaderResult<'a> {
88 fn from(result: Result<v1::Header<'a>, v1::BinaryParseError>) -> Self {
89 HeaderResult::V1(result)
90 }
91}
92
93impl<'a> From<Result<v2::Header<'a>, v2::ParseError>> for HeaderResult<'a> {
94 fn from(result: Result<v2::Header<'a>, v2::ParseError>) -> Self {
95 HeaderResult::V2(result)
96 }
97}
98
99impl<'a> PartialResult for HeaderResult<'a> {
100 fn is_incomplete(&self) -> bool {
101 match self {
102 Self::V1(result) => result.is_incomplete(),
103 Self::V2(result) => result.is_incomplete(),
104 }
105 }
106}
107
108impl<'a> HeaderResult<'a> {
109 pub fn parse(input: &'a [u8]) -> HeaderResult<'a> {
112 let header = v2::Header::try_from(input);
113
114 if header.is_complete() && header.is_err() {
115 v1::Header::try_from(input).into()
116 } else {
117 header.into()
118 }
119 }
120}