aoc_parse/parsers/
regex.rs1use std::{
4 any::{self, Any},
5 fmt::Display,
6};
7
8use regex::Regex;
9
10use crate::{parsers::BasicParseIter, ParseContext, Parser, Reported, Result};
11
12pub struct RegexParser<T, E> {
26 pub(crate) regex: fn() -> &'static Regex,
27 pub(crate) parse_fn: fn(&str) -> Result<T, E>,
28}
29
30impl<T, E> Clone for RegexParser<T, E> {
32 fn clone(&self) -> Self {
33 RegexParser {
34 regex: self.regex,
35 parse_fn: self.parse_fn,
36 }
37 }
38}
39
40impl<T, E> Copy for RegexParser<T, E> {}
41
42impl<T, E> Parser for RegexParser<T, E>
43where
44 T: Any + Clone,
45 E: Display,
46{
47 type Output = T;
48 type RawOutput = (T,);
49 type Iter<'parse> = BasicParseIter<T>
50 where
51 E: 'parse;
52
53 fn parse_iter<'parse>(
54 &'parse self,
55 context: &mut ParseContext<'parse>,
56 start: usize,
57 ) -> Result<Self::Iter<'parse>, Reported> {
58 match (self.regex)().find(&context.source()[start..]) {
59 None => Err(context.error_expected(start, any::type_name::<T>())),
60 Some(m) => match (self.parse_fn)(m.as_str()) {
61 Ok(value) => Ok(BasicParseIter {
62 end: start + m.end(),
63 value,
64 }),
65 Err(err) => Err(context.error_from_str_failed(
66 start,
67 start + m.end(),
68 any::type_name::<T>(),
69 format!("{err}"),
70 )),
71 },
72 }
73 }
74}