wiwi/parser/
stateless.rs

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// #[repr(transparent)]
177// pub struct ApplyMany<P, I, O, E>
178// where
179// 	I: Input
180// {
181// 	parser: P,
182// 	__marker: ParserPhantom<I, O, E>
183// }
184//
185// impl<P, I, O, E> Parser<I, Vec<O>, E> for ApplyMany<P, I, O, E>
186// where
187// 	I: Clone + Input,
188// 	P: Parser<I, O, E>
189// {
190// 	#[inline]
191// 	fn parse(&self, input: I) -> Result<I, Vec<O>, E> {
192// 		let mut out = Vec::new();
193// 		let mut remaining = input;
194//
195// 		loop {
196// 			// todo: i dont like this
197// 			match self.parser.parse(remaining.clone()) {
198// 				Ok(Success { output, remaining_input }) => {
199// 					out.push(output);
200// 					remaining = remaining_input;
201// 				}
202// 				Err(super::Error::NotEnoughData { .. }) => {
203// 					return Ok(Success { output: out, remaining_input: remaining })
204// 				}
205// 				Err(e) => { return Err(e) }
206// 			}
207// 		}
208// 	}
209// }
210
211#[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}