1#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
3pub struct Index<'a> {
4 pub remaining: &'a str,
6 pub lineno: usize,
7 pub colno: usize,
8}
9
10impl<'a> Index<'a> {
11 #[inline]
12 pub fn new(string: &'a str) -> Self {
13 Self {
14 remaining: string,
15 lineno: 0,
16 colno: 0,
17 }
18 }
19
20 #[inline]
21 pub fn peek(&self) -> Option<char> {
22 self.remaining.chars().next()
23 }
24
25 #[inline]
26 pub fn peek_multiple<const N: usize>(&self) -> Option<[char; N]> {
27 let mut peeked = ['\0'; N];
28 let mut chars = self.remaining.chars();
31 for p in peeked.iter_mut() {
32 let Some(c) = chars.next() else {
33 return None
34 };
35 *p = c;
36 }
37
38 Some(peeked)
39 }
40
41 #[inline]
42 pub fn next_multiple<const N: usize>(&mut self) -> Option<[char; N]> {
43 let mut all_next = ['\0'; N];
44 for n in all_next.iter_mut() {
47 let Some(c) = self.next() else {
48 return None
49 };
50 *n = c;
51 }
52 Some(all_next)
53 }
54
55 #[inline]
56 pub fn advance_to_end(&mut self) {
57 for _ in self.by_ref() {}
58 }
59}
60
61impl<'a> Iterator for Index<'a> {
62 type Item = char;
63
64 fn next(&mut self) -> Option<Self::Item> {
65 let c = self.remaining.chars().next()?;
66 let len = c.len_utf8();
67 self.remaining = self.remaining.get(len..)?;
68
69 if c == '\n' {
70 self.lineno += 1;
71 self.colno = 0;
72 } else {
73 self.colno += len;
74 }
75
76 Some(c)
77 }
78}
79
80#[derive(Debug)]
82pub struct ParseError {
83 pub lineno: usize,
84 pub colno: usize,
85}
86
87impl ParseError {
88 pub fn from_index(idx: Index<'_>) -> Self {
90 Self {
91 lineno: idx.lineno,
92 colno: idx.colno,
93 }
94 }
95}
96
97pub trait Parse: Sized {
98 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError>;
99
100 #[inline]
101 fn parse_raw_at(index: Index<'_>) -> Result<(&str, Index<'_>), ParseError> {
102 let (_, new_index) = Self::parse_at(index)?;
103
104 let consumed_len = index.remaining.len() - new_index.remaining.len();
105 let consumed = index
106 .remaining
107 .get(..consumed_len)
108 .ok_or(ParseError::from_index(index))?;
109
110 Ok((consumed, new_index))
111 }
112
113 #[inline]
114 fn parse(input: &str) -> Result<Self, ParseError> {
115 let idx = Index {
116 remaining: input,
117 lineno: 0,
118 colno: 0,
119 };
120
121 let (ret, remaining) = Self::parse_at(idx)?;
122 if remaining.remaining.is_empty() {
123 Ok(ret)
124 } else {
125 Err(ParseError::from_index(idx))
126 }
127 }
128}
129
130impl<T: Parse> Parse for Box<T> {
131 #[inline]
132 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
133 T::parse_at(index).map(|(val, idx)| (Box::new(val), idx))
134 }
135}
136
137impl Parse for bool {
138 #[inline]
139 fn parse_at(mut index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
140 match index.next_multiple() {
141 Some(['t', 'r', 'u', 'e']) => Ok((true, index)),
142 Some(['f', 'a', 'l', 's']) if index.next() == Some('e') => Ok((true, index)),
143 _ => Err(ParseError::from_index(index)),
144 }
145 }
146}
147
148impl Parse for u8 {
149 #[inline]
150 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
151 parse_unsigned(index)
152 }
153}
154
155impl Parse for u16 {
156 #[inline]
157 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
158 parse_unsigned(index)
159 }
160}
161
162impl Parse for u32 {
163 #[inline]
164 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
165 parse_unsigned(index)
166 }
167}
168
169impl Parse for u64 {
170 #[inline]
171 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
172 parse_unsigned(index)
173 }
174}
175
176impl Parse for u128 {
177 #[inline]
178 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
179 parse_unsigned(index)
180 }
181}
182
183impl Parse for usize {
184 #[inline]
185 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
186 parse_unsigned(index)
187 }
188}
189
190impl Parse for i8 {
191 #[inline]
192 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
193 parse_signed(index)
194 }
195}
196
197impl Parse for i16 {
198 #[inline]
199 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
200 parse_signed(index)
201 }
202}
203
204impl Parse for i32 {
205 #[inline]
206 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
207 parse_signed(index)
208 }
209}
210
211impl Parse for i64 {
212 #[inline]
213 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
214 parse_signed(index)
215 }
216}
217
218impl Parse for i128 {
219 #[inline]
220 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
221 parse_signed(index)
222 }
223}
224
225impl Parse for isize {
226 #[inline]
227 fn parse_at(index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
228 parse_signed(index)
229 }
230}
231
232impl Parse for String {
233 #[inline]
234 fn parse_at(mut index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
235 let s = index.remaining.to_string();
236 index.advance_to_end();
237 Ok((s, index))
238 }
239}
240
241impl Parse for char {
242 #[inline]
243 fn parse_at(mut index: Index<'_>) -> Result<(Self, Index<'_>), ParseError> {
244 index
245 .next()
246 .map(|c| (c, index))
247 .ok_or(ParseError::from_index(index))
248 }
249}
250
251fn parse_unsigned<I: num::Unsigned + num::CheckedAdd + num::CheckedMul + From<u8>>(
252 mut index: Index<'_>,
253) -> Result<(I, Index<'_>), ParseError> {
254 let mut value = None;
255
256 if let Some('0') = index.peek() {
258 index.next();
259 return match index.peek() {
260 Some('0'..='9') => Err(ParseError::from_index(index)),
261 _ => Ok((I::zero(), index)),
262 };
263 }
264
265 while let Some(c @ '0'..='9') = index.peek() {
267 let c_val = I::from((c as u8) - b'0');
268 value = value
269 .unwrap_or(I::zero())
270 .checked_mul(&10u8.into())
271 .and_then(|i| i.checked_add(&c_val));
272 if value.is_none() {
273 return Err(ParseError::from_index(index));
275 }
276
277 index.next();
278 }
279
280 value
282 .ok_or(ParseError::from_index(index))
283 .map(|i| (i, index))
284}
285
286fn parse_signed<I: num::Signed + num::CheckedAdd + num::CheckedSub + num::CheckedMul + From<i8>>(
287 mut index: Index<'_>,
288) -> Result<(I, Index<'_>), ParseError> {
289 let mut value = None;
290
291 let mut is_negative = false;
292
293 if let Some('-') = index.peek() {
294 is_negative = true;
295 index.next();
296 }
297
298 if let Some('0') = index.peek() {
300 index.next();
301 return match index.peek() {
302 Some('0'..='9') => Err(ParseError::from_index(index)),
303 _ => Ok((I::zero(), index)),
304 };
305 }
306
307 while let Some(c @ '0'..='9') = index.peek() {
309 let c_val = I::from((c as i8) - ('0' as i8));
310 value = value.unwrap_or(I::zero()).checked_mul(&10i8.into());
311
312 value = if is_negative {
313 value.and_then(|i| i.checked_sub(&c_val))
314 } else {
315 value.and_then(|i| i.checked_add(&c_val))
316 };
317
318 if value.is_none() {
319 return Err(ParseError::from_index(index));
321 }
322
323 index.next();
324 }
325
326 value
328 .ok_or(ParseError::from_index(index))
329 .map(|i| (i, index))
330}