1use crate::builder::Builder;
18use crate::builder::Regex;
19
20pub trait IntoRegex<B: Builder> {
21 fn r(self) -> Regex<B>;
22}
23
24pub trait IntoSymbol<B: Builder> {
25 fn s(self) -> Regex<B>;
26}
27
28pub trait IntoClosure<B: Builder> {
29 fn c(self) -> Regex<B>;
30}
31
32impl<B: Builder> IntoRegex<B> for () {
33 #[inline]
34 fn r(self) -> Regex<B> {
35 B::empty_set()
36 }
37}
38
39impl<B: Builder> IntoSymbol<B> for B::Symbol {
42 #[inline]
43 fn s(self) -> Regex<B> {
44 B::symbol(self)
45 }
46}
47
48impl<B: Builder> IntoClosure<B> for Regex<B> {
49 #[inline]
50 fn c(self) -> Regex<B> {
51 B::closure(self)
52 }
53}
54
55impl<B: Builder> std::ops::Add for Regex<B> {
56 type Output = Self;
57 #[inline]
58 fn add(self, rhs: Self) -> Self::Output {
59 B::concat(self, rhs)
60 }
61}
62
63impl<B: Builder, const X: usize> IntoRegex<B> for [Regex<B>; X] {
64 fn r(self) -> Regex<B> {
65 match X {
66 0 => B::empty_string(),
67 1 => self.into_iter().next().expect("can get only item"),
68 _ => self
69 .into_iter()
70 .reduce(B::concat)
71 .expect("can reduce multiple items"),
72 }
73 }
74}
75
76impl<B: Builder> std::ops::BitOr for Regex<B> {
77 type Output = Self;
78 #[inline]
79 fn bitor(self, rhs: Self) -> Self::Output {
80 B::or(self, rhs)
81 }
82}
83
84impl<B: Builder> std::ops::BitAnd for Regex<B> {
85 type Output = Self;
86 #[inline]
87 fn bitand(self, rhs: Self) -> Self::Output {
88 B::and(self, rhs)
89 }
90}
91
92impl<B: Builder> std::ops::Not for Regex<B> {
93 type Output = Self;
94 #[inline]
95 fn not(self) -> Self::Output {
96 B::complement(self)
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use crate::builder::ApproximatelySimilarCanonical;
103 use crate::builder::Pure;
104
105 use super::*;
106
107 #[test]
108 fn test_ops_pure() {
109 test_ops::<Pure<_>>()
110 }
111
112 #[test]
113 fn test_ops_asc() {
114 test_ops::<ApproximatelySimilarCanonical<_>>()
115 }
116
117 fn test_ops<B: Builder<Symbol = usize> + Clone>() {
118 let _: Vec<Regex<B>> = vec![
119 42.s(),
120 ().r() & 42.s(),
121 [1.s(), 2.s()].r(),
122 [1.s(), 3.s()].r() & 7.s(),
123 ().r() | 7.s(),
124 !().r(),
125 [].r(),
126 ];
127 }
128}