simple_json2/
parser.rs

1extern crate alloc;
2use alloc::vec::Vec;
3use crate::impls::{SimpleError, SimplePosition};
4use core::marker::PhantomData;
5
6pub trait Position: core::ops::Sub<Self, Output = i32> + Copy {
7	fn index(&self) -> u32;
8	fn line(&self) -> u32;
9	fn column(&self) -> u32;
10}
11
12pub trait Error {
13	type Position;
14
15	fn reasons(&self) -> &[(Option<Self::Position>, &'static str)];
16	fn add_reason(self, position: Option<Self::Position>, reason: &'static str) -> Self;
17	fn plain_str(reason: &'static str) -> Self;
18}
19
20pub trait Input: Default {
21	type Position: Position;
22	type Error: Error<Position = Self::Position>;
23	fn next(&self, pos: Self::Position) -> Result<(char, Self::Position), Self::Error>;
24	fn next_range(
25		&self,
26		start: Self::Position,
27		counts: u32,
28	) -> Result<(&str, Self::Position), Self::Error>;
29	fn error_at(&self, pos: Self::Position, reason: &'static str) -> Self::Error;
30}
31
32pub type ResultOf<I, O> = Result<(O, <I as Input>::Position), <I as Input>::Error>;
33
34pub trait Parser<I: Input> {
35	type Output;
36	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output>;
37}
38
39pub trait Predicate<T> {
40	fn eval(t: &T) -> bool;
41}
42
43pub struct ExpectChar<P>(PhantomData<P>);
44
45impl<P: Predicate<char>, I: Input> Parser<I> for ExpectChar<P> {
46	type Output = char;
47	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
48		let (c, next) = input
49			.next(current)
50			.map_err(|e| e.add_reason(Some(current), "ExpectChar"))?;
51		if P::eval(&c) {
52			Ok((c, next))
53		} else {
54			Err(input.error_at(current, "ExpectChar"))
55		}
56	}
57}
58
59pub struct Null;
60
61impl<I: Input> Parser<I> for Null {
62	type Output = ();
63	fn parse(_input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
64		Ok(((), current))
65	}
66}
67
68pub struct Concat<P, P2>(PhantomData<(P, P2)>);
69
70impl<I: Input, P: Parser<I>, P2: Parser<I>> Parser<I> for Concat<P, P2> {
71	type Output = (P::Output, P2::Output);
72	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
73		let (output1, pos) =
74			P::parse(input, current).map_err(|e| e.add_reason(Some(current), "Concat1"))?;
75		let (output2, pos) = P2::parse(input, pos).map_err(|e| e.add_reason(Some(current), "Concat2"))?;
76		Ok(((output1, output2), pos))
77	}
78}
79
80pub type Concat3<P, P2, P3> = Concat<P, Concat<P2, P3>>;
81pub type Concat4<P, P2, P3, P4> = Concat<P, Concat<P2, Concat<P3, P4>>>;
82pub type Concat5<P, P2, P3, P4, P5> = Concat<P, Concat<P2, Concat<P3, Concat<P4, P5>>>>;
83
84#[cfg_attr(feature = "std", derive(Debug))]
85pub enum Either<A, B> {
86	A(A),
87	B(B),
88}
89
90pub struct OneOf<P, P2>(PhantomData<(P, P2)>);
91
92impl<I: Input, P: Parser<I>, P2: Parser<I>> Parser<I> for OneOf<P, P2> {
93	type Output = Either<P::Output, P2::Output>;
94	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
95		P::parse(input, current)
96			.map(|(output, pos)| (Either::A(output), pos))
97			.or_else(|_| P2::parse(input, current).map(|(output, pos)| (Either::B(output), pos)))
98			.map_err(|e| e.add_reason(Some(current), "OneOf"))
99	}
100}
101
102pub type OneOf3<P, P2, P3> = OneOf<P, OneOf<P2, P3>>;
103pub type OneOf4<P, P2, P3, P4> = OneOf<P, OneOf3<P2, P3, P4>>;
104pub type OneOf5<P, P2, P3, P4, P5> = OneOf<P, OneOf4<P2, P3, P4, P5>>;
105pub type OneOf6<P, P2, P3, P4, P5, P6> = OneOf<P, OneOf5<P2, P3, P4, P5, P6>>;
106pub type OneOf7<P, P2, P3, P4, P5, P6, P7> = OneOf<P, OneOf6<P2, P3, P4, P5, P6, P7>>;
107pub type OneOf8<P, P2, P3, P4, P5, P6, P7, P8> = OneOf<P, OneOf7<P2, P3, P4, P5, P6, P7, P8>>;
108pub type OneOf9<P, P2, P3, P4, P5, P6, P7, P8, P9> =
109	OneOf<P, OneOf8<P2, P3, P4, P5, P6, P7, P8, P9>>;
110
111pub type ZeroOrOne<P> = OneOf<P, Null>;
112
113pub type ZeroOrMore<P> = OneOf<OneOrMore<P>, Null>;
114
115//pub type OneOrMore<P> = Concat<P, ZeroOrMore<P>>;
116pub struct OneOrMore<P>(PhantomData<P>);
117
118impl<I: Input, P: Parser<I>> Parser<I> for OneOrMore<P> {
119	type Output = Vec<P::Output>;
120	fn parse(input: &I, current: I::Position) -> ResultOf<I, Self::Output> {
121		let mut output_list = Vec::new();
122		let (output, mut pos) =
123			P::parse(input, current).map_err(|e| e.add_reason(Some(current), "OneOrMore"))?;
124		output_list.push(output);
125		loop {
126			if let Ok((output, next_pos)) = P::parse(input, pos) {
127				pos = next_pos;
128				output_list.push(output);
129			} else {
130				return Ok((output_list, pos));
131			}
132		}
133	}
134}
135
136impl Input for &str {
137	type Position = SimplePosition;
138	type Error = SimpleError;
139
140	fn next(&self, pos: Self::Position) -> Result<(char, Self::Position), Self::Error> {
141		self.chars()
142			.nth(pos.index() as usize)
143			.ok_or_else(|| self.error_at(pos, "Out of bounds"))
144			.map(|c| (c, pos.next(c)))
145	}
146
147	fn next_range(
148		&self,
149		start: Self::Position,
150		counts: u32,
151	) -> Result<(&str, Self::Position), Self::Error> {
152		let start_index = start.index() as usize;
153		let range = start_index..start_index + counts as usize;
154		self.get(range)
155			.map(|s| {
156				let mut pos = start;
157				for c in s.chars() {
158					pos = pos.next(c);
159				}
160				(s, pos)
161			})
162			.ok_or_else(|| self.error_at(start, "Out of bounds"))
163	}
164
165	fn error_at(&self, pos: Self::Position, reason: &'static str) -> Self::Error {
166		let mut reasons = Vec::new();
167		reasons.push((Some(pos), reason));
168		SimpleError { reasons }
169	}
170}
171
172#[macro_export]
173macro_rules! literals {
174	(
175		$(
176			$( #[ $attr:meta ] )*
177			$vis:vis $name:ident => $($value:expr)+;
178		)*
179	) => {
180		$(
181			$crate::literals!{
182				IMPL
183				$( #[ $attr ] )*
184				$vis $name => $($value)+
185			}
186		)*
187	};
188	(
189		IMPL
190		$( #[ $attr:meta ] )*
191		$vis:vis $name:ident => $($value:tt)+
192	) => (
193		paste::item! {
194			$vis struct [< $name Predicate >];
195			impl $crate::parser::Predicate<char> for [< $name Predicate >] {
196				fn eval(c: &char) -> bool {
197					match *c {
198						$($value)+ => true,
199						_ => false
200					}
201				}
202			}
203
204			$( #[ $attr ] )*
205			$vis type $name = $crate::parser::ExpectChar<[< $name Predicate >]>;
206		}
207	);
208}
209
210#[macro_export]
211macro_rules! parsers {
212	(
213		$(
214			$( #[ $attr:meta ] )*
215			$vis:vis $name:ident = $type:ty, $output_type:ty, ($output:ident) => $body:block;
216		)*
217	) => {
218		$(
219			$vis struct $name;
220			impl<I: $crate::parser::Input> $crate::parser::Parser<I> for $name {
221				type Output = $output_type;
222				fn parse(input: &I, current: I::Position) -> $crate::parser::ResultOf<I, Self::Output> {
223					let ($output, pos) = <$type as $crate::parser::Parser<I>>::parse(input, current)
224						.map_err(|e| <I::Error as $crate::parser::Error>::add_reason(e, Some(current), stringify!($name)))?;
225					let res = $body;
226					Ok((res, pos))
227				}
228			}
229		)*
230	};
231}