rama_haproxy/protocol/
mod.rs1mod ip;
8
9pub mod v1;
10pub mod v2;
11
12pub trait PartialResult {
15 fn is_complete(&self) -> bool {
19 !self.is_incomplete()
20 }
21
22 fn is_incomplete(&self) -> bool;
26}
27
28impl<T, E: PartialResult> PartialResult for Result<T, E> {
29 fn is_incomplete(&self) -> bool {
30 match self {
31 Ok(_) => false,
32 Err(error) => error.is_incomplete(),
33 }
34 }
35}
36
37impl PartialResult for v1::ParseError {
38 fn is_incomplete(&self) -> bool {
39 matches!(
40 self,
41 Self::Partial
42 | Self::MissingPrefix
43 | Self::MissingProtocol
44 | Self::MissingSourceAddress
45 | Self::MissingDestinationAddress
46 | Self::MissingSourcePort
47 | Self::MissingDestinationPort
48 | Self::MissingNewLine
49 )
50 }
51}
52
53impl PartialResult for v1::BinaryParseError {
54 fn is_incomplete(&self) -> bool {
55 match self {
56 Self::Parse(error) => error.is_incomplete(),
57 Self::InvalidUtf8(_) => false,
58 }
59 }
60}
61
62impl PartialResult for v2::ParseError {
63 fn is_incomplete(&self) -> bool {
64 matches!(self, Self::Incomplete(..) | Self::Partial(..))
65 }
66}
67
68#[derive(Debug, Clone, PartialEq, Eq)]
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>),
85 V2(Result<v2::Header<'a>, v2::ParseError>),
87}
88
89impl<'a> From<Result<v1::Header<'a>, v1::BinaryParseError>> for HeaderResult<'a> {
90 fn from(result: Result<v1::Header<'a>, v1::BinaryParseError>) -> Self {
91 HeaderResult::V1(result)
92 }
93}
94
95impl<'a> From<Result<v2::Header<'a>, v2::ParseError>> for HeaderResult<'a> {
96 fn from(result: Result<v2::Header<'a>, v2::ParseError>) -> Self {
97 HeaderResult::V2(result)
98 }
99}
100
101impl PartialResult for HeaderResult<'_> {
102 fn is_incomplete(&self) -> bool {
103 match self {
104 Self::V1(result) => result.is_incomplete(),
105 Self::V2(result) => result.is_incomplete(),
106 }
107 }
108}
109
110impl<'a> HeaderResult<'a> {
111 pub fn parse(input: &'a [u8]) -> Self {
114 let header = v2::Header::try_from(input);
115
116 if header.is_complete() && header.is_err() {
117 v1::Header::try_from(input).into()
118 } else {
119 header.into()
120 }
121 }
122}