1#[cfg(feature = "test-helpers")]
19pub mod test_helpers;
20
21use netgauze_locate::BinarySpan;
22use nom::IResult;
23use std::fmt::Debug;
24
25pub type Span<'a> = BinarySpan<&'a [u8]>;
26
27pub trait ReadablePdu<'a, Error: Debug> {
30 fn from_wire(buf: Span<'a>) -> IResult<Span<'a>, Self, Error>
31 where
32 Self: Sized;
33}
34
35pub trait ReadablePduWithOneInput<'a, T, ErrorType> {
38 fn from_wire(buf: Span<'a>, input: T) -> IResult<Span<'a>, Self, ErrorType>
39 where
40 Self: Sized;
41}
42
43pub trait ReadablePduWithTwoInputs<'a, T, U, ErrorType> {
46 fn from_wire(buf: Span<'a>, input1: T, input2: U) -> IResult<Span<'a>, Self, ErrorType>
47 where
48 Self: Sized;
49}
50
51pub trait ReadablePduWithThreeInputs<'a, I1, I2, I3, ErrorType> {
54 fn from_wire(
55 buf: Span<'a>,
56 input1: I1,
57 input2: I2,
58 input3: I3,
59 ) -> IResult<Span<'a>, Self, ErrorType>
60 where
61 Self: Sized;
62}
63
64#[allow(clippy::len_without_is_empty)]
67pub trait WritablePdu<ErrorType> {
68 const BASE_LENGTH: usize;
69
70 fn len(&self) -> usize;
76
77 fn write<T: std::io::Write>(&self, _writer: &mut T) -> Result<(), ErrorType>
78 where
79 Self: Sized;
80}
81
82#[allow(clippy::len_without_is_empty)]
85pub trait WritablePduWithOneInput<I, ErrorType> {
86 const BASE_LENGTH: usize;
87
88 fn len(&self, input: I) -> usize;
94
95 fn write<T: std::io::Write>(&self, _writer: &mut T, input: I) -> Result<(), ErrorType>
96 where
97 Self: Sized;
98}
99
100#[allow(clippy::len_without_is_empty)]
103pub trait WritablePduWithTwoInputs<I1, I2, ErrorType> {
104 const BASE_LENGTH: usize;
105
106 fn len(&self, input1: I1, input2: I2) -> usize;
112
113 fn write<T: std::io::Write>(
114 &self,
115 _writer: &mut T,
116 input1: I1,
117 input2: I2,
118 ) -> Result<(), ErrorType>
119 where
120 Self: Sized;
121}
122
123pub trait LocatedParsingError {
128 type Span;
129 type Error;
130
131 fn span(&self) -> &Self::Span;
132 fn error(&self) -> &Self::Error;
133}
134
135#[inline]
136pub fn parse_into_located<'a, Lin: Debug, L: From<Lin>, T: ReadablePdu<'a, Lin>>(
137 buf: Span<'a>,
138) -> IResult<Span<'a>, T, L> {
139 match T::from_wire(buf) {
140 Ok((buf, value)) => Ok((buf, value)),
141 Err(err) => match err {
142 nom::Err::Incomplete(needed) => Err(nom::Err::Incomplete(needed)),
143 nom::Err::Error(error) => Err(nom::Err::Error(error.into())),
144 nom::Err::Failure(failure) => Err(nom::Err::Failure(failure.into())),
145 },
146 }
147}
148
149#[inline]
150pub fn parse_into_located_one_input<
151 'a,
152 I,
153 Lin: Debug,
154 L: From<Lin>,
155 T: ReadablePduWithOneInput<'a, I, Lin>,
156>(
157 buf: Span<'a>,
158 input: I,
159) -> IResult<Span<'a>, T, L> {
160 match T::from_wire(buf, input) {
161 Ok((buf, value)) => Ok((buf, value)),
162 Err(err) => match err {
163 nom::Err::Incomplete(needed) => Err(nom::Err::Incomplete(needed)),
164 nom::Err::Error(error) => Err(nom::Err::Error(error.into())),
165 nom::Err::Failure(failure) => Err(nom::Err::Failure(failure.into())),
166 },
167 }
168}
169
170#[inline]
171pub fn parse_into_located_two_inputs<
172 'a,
173 I1,
174 I2,
175 Lin: Debug,
176 L: From<Lin>,
177 T: ReadablePduWithTwoInputs<'a, I1, I2, Lin>,
178>(
179 buf: Span<'a>,
180 input1: I1,
181 input2: I2,
182) -> IResult<Span<'a>, T, L> {
183 match T::from_wire(buf, input1, input2) {
184 Ok((buf, value)) => Ok((buf, value)),
185 Err(err) => match err {
186 nom::Err::Incomplete(needed) => Err(nom::Err::Incomplete(needed)),
187 nom::Err::Error(error) => Err(nom::Err::Error(error.into())),
188 nom::Err::Failure(failure) => Err(nom::Err::Failure(failure.into())),
189 },
190 }
191}
192
193#[inline]
194pub fn parse_into_located_three_inputs<
195 'a,
196 I1,
197 I2,
198 I3,
199 Lin: Debug,
200 L: From<Lin>,
201 T: ReadablePduWithThreeInputs<'a, I1, I2, I3, Lin>,
202>(
203 buf: Span<'a>,
204 input1: I1,
205 input2: I2,
206 input3: I3,
207) -> IResult<Span<'a>, T, L> {
208 match T::from_wire(buf, input1, input2, input3) {
209 Ok((buf, value)) => Ok((buf, value)),
210 Err(err) => match err {
211 nom::Err::Incomplete(needed) => Err(nom::Err::Incomplete(needed)),
212 nom::Err::Error(error) => Err(nom::Err::Error(error.into())),
213 nom::Err::Failure(failure) => Err(nom::Err::Failure(failure.into())),
214 },
215 }
216}
217
218#[inline]
220pub fn parse_till_empty<'a, T: ReadablePdu<'a, E>, E: Debug>(
221 buf: Span<'a>,
222) -> IResult<Span<'a>, Vec<T>, E> {
223 let mut buf = buf;
224 let mut ret = Vec::new();
225 while !buf.is_empty() {
226 let (tmp, element) = T::from_wire(buf)?;
227 ret.push(element);
228 buf = tmp;
229 }
230 Ok((buf, ret))
231}
232
233#[inline]
235pub fn parse_till_empty_into_located<'a, Lin: Debug, L: From<Lin>, T: ReadablePdu<'a, Lin>>(
236 buf: Span<'a>,
237) -> IResult<Span<'a>, Vec<T>, L> {
238 let mut buf = buf;
239 let mut ret = Vec::new();
240 while !buf.is_empty() {
241 let (tmp, element) = parse_into_located(buf)?;
242 ret.push(element);
243 buf = tmp;
244 }
245 Ok((buf, ret))
246}
247
248#[inline]
250pub fn parse_till_empty_with_one_input<
251 'a,
252 I: Clone,
253 T: ReadablePduWithOneInput<'a, I, E>,
254 E: Debug,
255>(
256 buf: Span<'a>,
257 input: I,
258) -> IResult<Span<'a>, Vec<T>, E> {
259 let mut buf = buf;
260 let mut ret = Vec::new();
261 while !buf.is_empty() {
262 let (tmp, element) = T::from_wire(buf, input.clone())?;
263 ret.push(element);
264 buf = tmp;
265 }
266 Ok((buf, ret))
267}
268
269#[inline]
271pub fn parse_till_empty_into_with_one_input_located<
272 'a,
273 I: Clone,
274 Lin: Debug,
275 L: From<Lin>,
276 T: ReadablePduWithOneInput<'a, I, Lin>,
277>(
278 buf: Span<'a>,
279 input: I,
280) -> IResult<Span<'a>, Vec<T>, L> {
281 let mut buf = buf;
282 let mut ret = Vec::new();
283 while !buf.is_empty() {
284 let (tmp, element) = parse_into_located_one_input(buf, input.clone())?;
285 ret.push(element);
286 buf = tmp;
287 }
288 Ok((buf, ret))
289}
290
291#[inline]
293pub fn parse_till_empty_into_with_two_inputs_located<
294 'a,
295 I1: Clone,
296 I2: Clone,
297 Lin: Debug,
298 L: From<Lin>,
299 T: ReadablePduWithTwoInputs<'a, I1, I2, Lin>,
300>(
301 buf: Span<'a>,
302 input1: I1,
303 input2: I2,
304) -> IResult<Span<'a>, Vec<T>, L> {
305 let mut buf = buf;
306 let mut ret = Vec::new();
307 while !buf.is_empty() {
308 let (tmp, element) = parse_into_located_two_inputs(buf, input1.clone(), input2.clone())?;
309 ret.push(element);
310 buf = tmp;
311 }
312 Ok((buf, ret))
313}
314
315#[inline]
317pub fn parse_till_empty_into_with_three_inputs_located<
318 'a,
319 I1: Clone,
320 I2: Clone,
321 I3: Clone,
322 Lin: Debug,
323 L: From<Lin>,
324 T: ReadablePduWithThreeInputs<'a, I1, I2, I3, Lin>,
325>(
326 buf: Span<'a>,
327 input1: I1,
328 input2: I2,
329 input3: I3,
330) -> IResult<Span<'a>, Vec<T>, L> {
331 let mut buf = buf;
332 let mut ret = Vec::new();
333 while !buf.is_empty() {
334 let (tmp, element) =
335 parse_into_located_three_inputs(buf, input1.clone(), input2.clone(), input3.clone())?;
336 ret.push(element);
337 buf = tmp;
338 }
339 Ok((buf, ret))
340}
341
342#[derive(Debug, serde::Serialize, serde::Deserialize)]
343#[serde(remote = "nom::error::ErrorKind")]
344pub enum ErrorKindSerdeDeref {
345 Tag,
346 MapRes,
347 MapOpt,
348 Alt,
349 IsNot,
350 IsA,
351 SeparatedList,
352 SeparatedNonEmptyList,
353 Many0,
354 Many1,
355 ManyTill,
356 Count,
357 TakeUntil,
358 LengthValue,
359 TagClosure,
360 Alpha,
361 Digit,
362 HexDigit,
363 OctDigit,
364 AlphaNumeric,
365 Space,
366 MultiSpace,
367 LengthValueFn,
368 Eof,
369 Switch,
370 TagBits,
371 OneOf,
372 NoneOf,
373 Char,
374 CrLf,
375 RegexpMatch,
376 RegexpMatches,
377 RegexpFind,
378 RegexpCapture,
379 RegexpCaptures,
380 TakeWhile1,
381 Complete,
382 Fix,
383 Escaped,
384 EscapedTransform,
385 NonEmpty,
386 ManyMN,
387 Not,
388 Permutation,
389 Verify,
390 TakeTill1,
391 TakeWhileMN,
392 TooLarge,
393 Many0Count,
394 Many1Count,
395 Float,
396 Satisfy,
397 Fail,
398}