1use crate::prelude::*;
2use crate::num::*;
3use super::{ max_init_cap, util, Error, Input, Needle, ParserPhantom, Result, Success };
4use std::num::NonZero;
5
6pub trait Parser<I, O, E = ()>
7where
8 I: Input
9{
10 fn parse(&self, input: I) -> Result<I, O, E>;
11
12 #[inline]
13 fn map<F, O2>(self, f: F) -> util::Map<Self, F, O>
14 where
15 Self: Sized,
16 F: Fn(O) -> O2
17 {
18 util::map(self, f)
19 }
20}
21
22impl<F, I, O, E> Parser<I, O, E> for F
23where
24 I: Input,
25 F: Fn(I) -> Result<I, O, E>
26{
27 #[inline]
28 fn parse(&self, input: I) -> Result<I, O, E> {
29 self(input)
30 }
31}
32
33#[inline]
34pub fn delimited<P, I, O, E, EReal, PBefore, OBefore, EBefore, PAfter, OAfter, EAfter>(
35 parser_before: PBefore,
36 parser: P,
37 parser_after: PAfter
38) -> Delimited<P, I, O, E, EReal, PBefore, OBefore, EBefore, PAfter, OAfter, EAfter>
39where
40 I: Input,
41 PBefore: Parser<I, OBefore, EBefore>,
42 P: Parser<I, O, E>,
43 PAfter: Parser<I, OAfter, EAfter>,
44 EBefore: Into<EReal>,
45 E: Into<EReal>,
46 EAfter: Into<EReal>
47{
48 Delimited {
49 parser_before,
50 parser,
51 parser_after,
52 __marker: PhantomData
53 }
54}
55
56macro_rules! decl_num_fn {
57 { $($(#[$meta:meta])* $struct:ident $fn:ident)* } => {
58 $(
59 $(#[$meta])*
60 #[inline]
61 pub fn $fn() -> $struct {
62 let inner = Number { inner: take_array(), __marker: PhantomData };
63 $struct { inner }
64 }
65 )*
66 };
67}
68
69decl_num_fn! {
70 NumU8LE num_u8_le
71 NumU8BE num_u8_be
72 NumU8NE num_u8_ne
73
74 NumU16LE num_u16_le
75 NumU16BE num_u16_be
76 NumU16NE num_u16_ne
77
78 NumU32LE num_u32_le
79 NumU32BE num_u32_be
80 NumU32NE num_u32_ne
81
82 NumU64LE num_u64_le
83 NumU64BE num_u64_be
84 NumU64NE num_u64_ne
85
86 NumU128LE num_u128_le
87 NumU128BE num_u128_be
88 NumU128NE num_u128_ne
89
90 NumI8LE num_i8_le
91 NumI8BE num_i8_be
92 NumI8NE num_i8_ne
93
94 NumI16LE num_i16_le
95 NumI16BE num_i16_be
96 NumI16NE num_i16_ne
97
98 NumI32LE num_i32_le
99 NumI32BE num_i32_be
100 NumI32NE num_i32_ne
101
102 NumI64LE num_i64_le
103 NumI64BE num_i64_be
104 NumI64NE num_i64_ne
105
106 NumI128LE num_i128_le
107 NumI128BE num_i128_be
108 NumI128NE num_i128_ne
109
110 NumF32LE num_f32_le
111 NumF32BE num_f32_be
112 NumF32NE num_f32_ne
113
114 NumF64LE num_f64_le
115 NumF64BE num_f64_be
116 NumF64NE num_f64_ne
117
118 NumUsizeLE num_usize_le
119 NumUsizeBE num_usize_be
120 NumUsizeNE num_usize_ne
121 NumIsizeLE num_isize_le
122 NumIsizeBE num_isize_be
123 NumIsizeNE num_isize_ne
124}
125
126#[inline]
127pub fn repeat<P, I, O, E>(parser: P, count: usize) -> Repeat<P, I, O, E>
128where
129 I: Clone + Input,
130 P: Parser<I, O, E>
131{
132 Repeat { parser, count, __marker: PhantomData }
133}
134
135#[inline]
136pub fn spin<P, I, O, E>(parser: P) -> Spin<P, I, O, E>
137where
138 I: Clone + Input,
139 P: Parser<I, O, E>
140{
141 Spin { parser, __marker: PhantomData }
142}
143
144#[inline]
145pub fn tag<T>(tag: T) -> Tag<T> {
146 Tag { tag }
147}
148
149#[inline]
150pub fn take<N>(amount: N) -> Take
151where
152 N: IntoUsize
153{
154 Take { amount: amount.into_usize() }
155}
156
157#[inline]
158pub fn take_array<const N: usize>() -> TakeArray<N> {
159 TakeArray { __private: () }
160}
161
162#[inline]
163pub fn take_const<const N: usize>() -> TakeConst<N> {
164 TakeConst { __private: () }
165}
166
167#[inline]
168pub fn void<P, I, O, E>(parser: P) -> Void<P, I, O, E>
169where
170 I: Input,
171 P: Parser<I, O, E>
172{
173 Void { parser, __marker: PhantomData }
174}
175
176#[expect(
212 clippy::type_complexity,
213 reason = "good naming makes it look alright I guess lol"
214)]
215pub struct Delimited<P, I, O, E, EReal, PBefore, OBefore, EBefore, PAfter, OAfter, EAfter>
216where
217 I: Input
218{
219 parser_before: PBefore,
220 parser: P,
221 parser_after: PAfter,
222 __marker: PhantomData<(
223 ParserPhantom<I, OBefore, EBefore>,
224 ParserPhantom<I, O, E>,
225 ParserPhantom<I, OAfter, EAfter>,
226 fn() -> EReal
227 )>
228}
229
230impl<P, I, O, E, EReal, PBefore, OBefore, EBefore, PAfter, OAfter, EAfter> Parser<I, O, EReal>
231for Delimited<P, I, O, E, EReal, PBefore, OBefore, EBefore, PAfter, OAfter, EAfter>
232where
233 I: Input,
234 PBefore: Parser<I, OBefore, EBefore>,
235 P: Parser<I, O, E>,
236 PAfter: Parser<I, OAfter, EAfter>,
237 EBefore: Into<EReal>,
238 E: Into<EReal>,
239 EAfter: Into<EReal>
240{
241 #[inline]
242 fn parse(&self, input: I) -> Result<I, O, EReal> {
243 let Success {
244 output: _output_before,
245 remaining_input: input
246 } = self.parser_before.parse(input).map_err(Error::into)?;
247
248 let Success {
249 output,
250 remaining_input: input
251 } = self.parser.parse(input).map_err(Error::into)?;
252
253 let Success {
254 output: _output_after,
255 remaining_input
256 } = self.parser_after.parse(input).map_err(Error::into)?;
257
258 Ok(Success { output, remaining_input })
259 }
260}
261
262#[repr(transparent)]
263struct Number<Num, E, const N: usize>
264where
265 Num: ArrayConversions<N>,
266 E: Endian<Num, N>
267{
268 inner: TakeArray<N>,
269 __marker: PhantomData<(fn() -> Num, E)>
270}
271
272impl<'h, Num, E, const N: usize> Parser<&'h [u8], Num> for Number<Num, E, N>
273where
274 Num: ArrayConversions<N>,
275 E: Endian<Num, N>
276{
277 #[inline]
278 fn parse(&self, input: &'h [u8]) -> Result<&'h [u8], Num> {
279 self.inner.parse(input).map(|Success { output, remaining_input }| Success {
280 output: E::from_bytes(output),
281 remaining_input
282 })
283 }
284}
285
286macro_rules! decl_num_struct {
287 { $($(#[$meta:meta])* $num:ident $n:literal $struct_le:ident $struct_be:ident $struct_ne:ident )* } => {
288 $(
289 decl_num_struct! { @impl $(#[$meta])* $num EndianLittle $n $struct_le }
290 decl_num_struct! { @impl $(#[$meta])* $num EndianBig $n $struct_be }
291 decl_num_struct! { @impl $(#[$meta])* $num EndianNative $n $struct_ne }
292 )*
293 };
294
295 { @impl $(#[$meta:meta])* $num:ident $endian:ident $n:literal $struct:ident } => {
296 $(#[$meta])*
297 #[repr(transparent)]
298 pub struct $struct {
299 inner: Number<$num, $endian, $n>
300 }
301
302 $(#[$meta])*
303 impl<'h> Parser<&'h [u8], $num> for $struct {
304 #[inline]
305 fn parse(&self, input: &'h [u8]) -> Result<&'h [u8], $num> {
306 self.inner.parse(input)
307 }
308 }
309 };
310}
311
312decl_num_struct! {
313 u8 1 NumU8LE NumU8BE NumU8NE
314 u16 2 NumU16LE NumU16BE NumU16NE
315 u32 4 NumU32LE NumU32BE NumU32NE
316 u64 8 NumU64LE NumU64BE NumU64NE
317 u128 16 NumU128LE NumU128BE NumU128NE
318
319 i8 1 NumI8LE NumI8BE NumI8NE
320 i16 2 NumI16LE NumI16BE NumI16NE
321 i32 4 NumI32LE NumI32BE NumI32NE
322 i64 8 NumI64LE NumI64BE NumI64NE
323 i128 16 NumI128LE NumI128BE NumI128NE
324
325 f32 4 NumF32LE NumF32BE NumF32NE
326 f64 8 NumF64LE NumF64BE NumF64NE
327
328 #[cfg(target_pointer_width = "16")]
329 usize 2 NumUsizeLE NumUsizeBE NumUsizeNE
330 #[cfg(target_pointer_width = "16")]
331 isize 2 NumIsizeLE NumIsizeBE NumIsizeNE
332
333 #[cfg(target_pointer_width = "32")]
334 usize 4 NumUsizeLE NumUsizeBE NumUsizeNE
335 #[cfg(target_pointer_width = "32")]
336 isize 4 NumIsizeLE NumIsizeBE NumIsizeNE
337
338 #[cfg(target_pointer_width = "64")]
339 usize 8 NumUsizeLE NumUsizeBE NumUsizeNE
340 #[cfg(target_pointer_width = "64")]
341 isize 8 NumIsizeLE NumIsizeBE NumIsizeNE
342}
343
344pub struct Repeat<P, I, O, E>
345where
346 I: Input
347{
348 parser: P,
349 count: usize,
350 __marker: ParserPhantom<I, O, E>
351}
352
353impl<P, I, O, E> Parser<I, Vec<O>, E> for Repeat<P, I, O, E>
354where
355 I: Clone + Input,
356 P: Parser<I, O, E>
357{
358 #[inline]
359 fn parse(&self, mut input: I) -> Result<I, Vec<O>, E> {
360 let mut out = Vec::with_capacity(usize::max(const { max_init_cap::<O>() }, self.count));
361
362 for _ in 0..self.count {
363 let Success { output, remaining_input } = self.parser.parse(input.clone())?;
364 out.push(output);
365 input = remaining_input;
366 }
367
368 Ok(Success { output: out, remaining_input: input })
369 }
370}
371
372pub struct Spin<P, I, O, E>
373where
374 I: Input
375{
376 parser: P,
377 __marker: ParserPhantom<I, O, E>
378}
379
380impl<P, I, O, E> Parser<I, Vec<O>, E> for Spin<P, I, O, E>
381where
382 I: Clone + Input,
383 P: Parser<I, O, E>
384{
385 #[inline]
386 fn parse(&self, mut input: I) -> Result<I, Vec<O>, E> {
387 let mut out = Vec::new();
388
389 loop {
390 match self.parser.parse(input.clone()) {
391 Ok(Success { output, remaining_input }) => {
392 out.push(output);
393 input = remaining_input;
394 }
395 Err(Error::NotEnoughData { missing: _ }) => {
396 return Ok(Success { output: out, remaining_input: input })
397 }
398 Err(e) => { return Err(e) }
399 }
400 }
401 }
402}
403
404#[repr(transparent)]
405pub struct Tag<T> {
406 tag: T
407}
408
409impl<I, T> Parser<I, ()> for Tag<T>
410where
411 I: Input,
412 T: Needle<I>
413{
414 #[inline]
415 fn parse(&self, input: I) -> Result<I, ()> {
416 let true = input.len() >= self.tag.len() else {
417 return Err(Error::NotEnoughData {
418 missing: NonZero::new(self.tag.len() - input.len())
419 })
420 };
421
422 input.starts_with(&self.tag)
423 .then(|| input.take_first(self.tag.len()))
424 .flatten()
425 .map(|(_, remaining_input)| Success { output: (), remaining_input })
426 .ok_or_else(|| Error::Error { error: () })
427 }
428}
429
430#[repr(transparent)]
431pub struct Take {
432 amount: usize
433}
434
435impl<I> Parser<I, I> for Take
436where
437 I: Input
438{
439 #[inline]
440 fn parse(&self, input: I) -> Result<I, I> {
441 input.take_first(self.amount)
442 .map(|(output, remaining_input)| Success { output, remaining_input })
443 .ok_or_else(|| Error::NotEnoughData {
444 missing: NonZero::new(self.amount - input.len())
445 })
446 }
447}
448
449#[repr(transparent)]
450pub struct TakeArray<const N: usize> {
451 __private: ()
452}
453
454impl<I, const N: usize> Parser<I, I::ConstSizeOwned<N>> for TakeArray<N>
455where
456 I: Input
457{
458 #[inline]
459 fn parse(&self, input: I) -> Result<I, I::ConstSizeOwned<N>> {
460 input.take_first_const_owned()
461 .map(|(output, remaining_input)| Success { output, remaining_input })
462 .ok_or_else(|| Error::NotEnoughData {
463 missing: NonZero::new(N - input.len())
464 })
465 }
466}
467
468#[repr(transparent)]
469pub struct TakeConst<const N: usize> {
470 __private: ()
471}
472
473impl<I, const N: usize> Parser<I, I::ConstSize<N>> for TakeConst<N>
474where
475 I: Input
476{
477 #[inline]
478 fn parse(&self, input: I) -> Result<I, I::ConstSize<N>> {
479 input.take_first_const()
480 .map(|(output, remaining_input)| Success { output, remaining_input })
481 .ok_or_else(|| Error::NotEnoughData {
482 missing: NonZero::new(N - input.len())
483 })
484 }
485}
486
487#[repr(transparent)]
488pub struct Void<P, I, O, E>
489where
490 I: Input
491{
492 parser: P,
493 __marker: ParserPhantom<I, O, E>
494}
495
496impl<P, I, O, E> Parser<I, (), E> for Void<P, I, O, E>
497where
498 I: Input,
499 P: Parser<I, O, E>
500{
501 #[inline]
502 fn parse(&self, input: I) -> Result<I, (), E> {
503 let Success { output: _void, remaining_input } = self.parser.parse(input)?;
504 Ok(Success { output: (), remaining_input })
505 }
506}