iregex_syntax/
build.rs

1use iregex::automata::{any_char, AnyRange, RangeSet};
2
3use crate::{Ast, Atom, Charset, Class, Classes, Disjunction, Repeat, Sequence};
4
5impl Ast {
6	pub fn build(&self) -> iregex::IRegEx {
7		let root = self.disjunction.build();
8
9		iregex::IRegEx {
10			root,
11			prefix: if self.start_anchor {
12				iregex::Affix::Anchor
13			} else {
14				iregex::Affix::Any
15			},
16			suffix: if self.end_anchor {
17				iregex::Affix::Anchor
18			} else {
19				iregex::Affix::Any
20			},
21		}
22	}
23}
24
25impl Disjunction {
26	pub fn build(&self) -> iregex::Alternation {
27		self.iter().map(Sequence::build).collect()
28	}
29}
30
31impl Sequence {
32	pub fn build(&self) -> iregex::Concatenation {
33		self.iter().map(Atom::build).collect()
34	}
35}
36
37impl Atom {
38	pub fn build(&self) -> iregex::Atom {
39		match self {
40			Self::Any => iregex::Atom::Token(any_char()),
41			Self::Char(c) => iregex::Atom::Token(RangeSet::from_iter([*c])),
42			Self::Set(set) => iregex::Atom::Token(set.build()),
43			Self::Group(g) => iregex::Atom::alternation(g.build()),
44			Self::Repeat(atom, repeat) => iregex::Atom::Repeat(atom.build().into(), repeat.build()),
45		}
46	}
47}
48
49impl Classes {
50	pub fn build(&self) -> iregex::automata::RangeSet<char> {
51		let mut result = iregex::automata::RangeSet::new();
52
53		for c in self {
54			result.extend(c.build());
55		}
56
57		result
58	}
59}
60
61impl Class {
62	pub fn build(&self) -> iregex::automata::RangeSet<char> {
63		todo!()
64	}
65}
66
67impl Charset {
68	pub fn build(&self) -> iregex::automata::RangeSet<char> {
69		let mut result = self.set.clone();
70		result.extend(self.classes.build());
71
72		if self.negative {
73			return result.gaps().map(AnyRange::cloned).collect();
74		} else {
75			result
76		}
77	}
78}
79
80impl Repeat {
81	pub fn build(&self) -> iregex::Repeat {
82		iregex::Repeat {
83			min: self.min,
84			max: self.max,
85		}
86	}
87}