c_its_parser/transport/
decode.rs1use nom::bytes::streaming::take;
2use nom::combinator::{into, map_res};
3use nom::error::{ErrorKind, FromExternalError, ParseError};
4use nom::sequence::pair;
5
6#[derive(Debug, PartialEq)]
7pub enum DecodeError<I> {
8 IntegerError(alloc::string::String),
9 IPv6Parsing(alloc::string::String),
10 Nom(I, ErrorKind),
11 #[cfg(feature = "json")]
12 Json(alloc::string::String),
13}
14
15impl<I> ParseError<I> for DecodeError<I> {
16 fn from_error_kind(input: I, kind: ErrorKind) -> Self {
17 DecodeError::Nom(input, kind)
18 }
19
20 fn append(_: I, _: ErrorKind, other: Self) -> Self {
21 other
22 }
23}
24
25impl<I, E> FromExternalError<I, E> for DecodeError<I> {
26 fn from_external_error(input: I, kind: ErrorKind, _: E) -> Self {
27 DecodeError::Nom(input, kind)
28 }
29}
30
31pub type IResult<I, T> = nom::IResult<I, T, DecodeError<I>>;
32
33pub trait Decode: Sized {
34 fn decode(input: &[u8]) -> IResult<&[u8], Self>;
50}
51
52impl Decode for super::BasicTransportAHeader {
53 fn decode(input: &[u8]) -> IResult<&[u8], Self> {
54 into(pair(u16_from_be_bytes, u16_from_be_bytes))(input)
55 }
56}
57
58impl From<(u16, u16)> for super::BasicTransportAHeader {
59 fn from(value: (u16, u16)) -> Self {
60 Self {
61 destination_port: value.0,
62 source_port: value.1,
63 }
64 }
65}
66
67impl super::BasicTransportAHeader {
68 #[cfg(feature = "json")]
69 pub fn decode_from_json(input: &str) -> Result<Self, DecodeError<&str>> {
74 serde_json::from_str(input)
75 .map_err(|e| DecodeError::Json(alloc::format!("Error encoding to JSON: {e:?}")))
76 }
77}
78
79impl Decode for super::BasicTransportBHeader {
80 fn decode(input: &[u8]) -> IResult<&[u8], Self> {
81 into(pair(u16_from_be_bytes, u16_from_be_bytes))(input)
82 }
83}
84
85impl From<(u16, u16)> for super::BasicTransportBHeader {
86 fn from(value: (u16, u16)) -> Self {
87 Self {
88 destination_port: value.0,
89 destination_port_info: value.1,
90 }
91 }
92}
93
94impl super::BasicTransportBHeader {
95 #[cfg(feature = "json")]
96 pub fn decode_from_json(input: &str) -> Result<Self, DecodeError<&str>> {
101 serde_json::from_str(input)
102 .map_err(|e| DecodeError::Json(alloc::format!("Error encoding to JSON: {e:?}")))
103 }
104}
105
106fn u16_from_be_bytes(input: &[u8]) -> IResult<&[u8], u16> {
107 map_res(take(2usize), |slice: &[u8]| {
108 slice.try_into().map(u16::from_be_bytes).map_err(|e| {
109 DecodeError::IntegerError::<&[u8]>(alloc::format!(
110 "Failed to construct integer from bytes: {e:?}"
111 ))
112 })
113 })(input)
114}
115
116impl Decode for super::IPv6Header {
117 fn decode(input: &[u8]) -> IResult<&[u8], Self> {
118 etherparse::PacketHeaders::from_ip_slice(input)
119 .map(|headers| {
120 let first_after_headers = headers
121 .net
122 .as_ref()
123 .map_or(0, etherparse::NetHeaders::header_len)
124 + headers
125 .link
126 .as_ref()
127 .map_or(0, etherparse::LinkHeader::header_len)
128 + headers
129 .transport
130 .as_ref()
131 .map_or(0, etherparse::TransportHeader::header_len)
132 + headers
133 .link_exts
134 .first()
135 .map_or(0, etherparse::LinkExtHeader::header_len);
136 (
137 &input[first_after_headers..],
138 super::IPv6Header::from(headers),
139 )
140 })
141 .map_err(|e| {
142 nom::Err::Error(DecodeError::IPv6Parsing(alloc::format!(
143 "Error parsing IPv6 Header: {e:?}"
144 )))
145 })
146 }
147}
148
149impl From<etherparse::PacketHeaders<'_>> for super::IPv6Header {
150 fn from(value: etherparse::PacketHeaders<'_>) -> Self {
151 Self {
152 ip: value.net,
153 link: value.link,
154 transport: value.transport,
155 link_ext: value.link_exts.first().cloned(),
156 }
157 }
158}
159
160#[cfg(test)]
161mod tests {}