wiwi/
parser.rs

1use crate::prelude::*;
2use std::num::NonZero;
3
4pub use input::{ Input, Needle };
5pub use stateful::ParserStateful;
6pub use stateless::Parser;
7
8pub mod input;
9pub mod stateful;
10pub mod stateless;
11pub mod util;
12
13pub struct Success<I, O> {
14	pub output: O,
15	pub remaining_input: I,
16}
17
18#[derive(Debug)]
19pub enum Error<E> {
20	NotEnoughData { missing: Option<NonZero<usize>> },
21	Error { error: E },
22	Fatal { error: E }
23}
24
25pub type Result<I, O, E = ()> = std::result::Result<Success<I, O>, Error<E>>;
26
27pub type ParserPhantom<I, O, E = ()> = PhantomData<ParserPhantomImpl<I, O, E>>;
28
29/// This is an implementation detail of [`ParserPhantom`]
30///
31/// This helps to enforce the trait bounds of [`Parser`]/[`ParserStateful`] in
32/// [`ParserPhantom`] type, to work around the fact that type aliases don't
33/// enforce their trait bounds for now, which is a known rust type checker limitation.
34#[doc(hidden)]
35pub struct ParserPhantomImpl<I, O, E>
36where
37	I: Input
38{
39	__inner: fn(I) -> Result<I, O, E>
40}
41
42impl<E> Error<E> {
43	#[inline]
44	fn from<EFrom>(error: Error<EFrom>) -> Self
45	where
46		EFrom: Into<E>
47	{
48		use self::Error::*;
49
50		match error {
51			NotEnoughData { missing } => { NotEnoughData { missing } }
52			Error { error } => { Error { error: error.into() } }
53			Fatal { error } => { Fatal { error: error.into() } }
54		}
55	}
56
57	#[inline]
58	fn into<EInto>(self) -> Error<EInto>
59	where
60		E: Into<EInto>
61	{
62		Error::from(self)
63	}
64}
65
66#[inline]
67const fn max_init_cap<T>() -> usize {
68	// 1 MiB
69	const MAX_BYTES: usize = 1024 * 1024;
70
71	if size_of::<T>() == 0 {
72		// ZST, doesn't really matter honestly
73		MAX_BYTES
74	} else {
75		MAX_BYTES / size_of::<T>()
76	}
77}