1use std::fmt::{Debug, Display};
2use std::ops::{Range, RangeBounds};
3
4use unique_pointer::UniquePointer;
5
6use crate::{Match, Position, Production, Span, State};
7
8pub trait Literal: Sized + Display + Debug + Clone {}
9pub trait StackRange: RangeBounds<isize> + Debug + Clone {}
10
11pub trait Matcher: Sized + Debug + Clone {
12 fn name(&self) -> &str;
13 fn to_str(&self) -> String;
14 fn as_production(&self) -> Production;
15 fn is_match(&self, state: &mut State, input: &str, start: &Position) -> Option<Match> {
16 None
17 }
18 fn as_mut(&self) -> &mut Self {
19 UniquePointer::read_only(self).extend_lifetime_mut()
20 }
21 fn to_dbg(&self) -> String {
22 format!("{:#?}", self.to_str())
23 }
24 fn span(&self, start: &Position, input: &str) -> Span {
25 start.span_to(input)
26 }
27}
28
29#[macro_export]
30macro_rules! impl_matcher_for_ref {
31 ($($type:tt)*) => {
32 impl Matcher for &$($type)* {
33 fn is_match(&self, state: &mut State, input: &str, start: &Position) -> Option<Match> {
34 (*self).is_match(state, input, start)
35 }
36
37 fn name(&self) -> &str {
38 (*self).name()
39 }
40
41 fn to_str(&self) -> String {
42 (*self).to_str()
43 }
44
45 fn as_production(&self) -> Production {
46 (*self).as_production()
47 }
48 }
49 };
50}