summaryrefslogtreecommitdiff
path: root/src/csets.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/csets.rs')
-rw-r--r--src/csets.rs69
1 files changed, 68 insertions, 1 deletions
diff --git a/src/csets.rs b/src/csets.rs
index 8c6767c..0f4b4d0 100644
--- a/src/csets.rs
+++ b/src/csets.rs
@@ -1,7 +1,31 @@
use std::collections::HashSet;
-pub trait CharacterSet {
+pub trait CharacterSet: Sized {
fn contains(&self, ch: char) -> bool;
+
+ fn union<Other: CharacterSet>(self, other: Other) -> CharacterSetUnion<Self, Other> {
+ CharacterSetUnion {
+ first: self,
+ second: other,
+ }
+ }
+
+ fn intersection<Other: CharacterSet>(
+ self,
+ other: Other,
+ ) -> CharacterSetIntersection<Self, Other> {
+ CharacterSetIntersection {
+ first: self,
+ second: other,
+ }
+ }
+
+ fn difference<Other: CharacterSet>(self, other: Other) -> CharacterSetDifference<Self, Other> {
+ CharacterSetDifference {
+ first: self,
+ second: other,
+ }
+ }
}
pub struct AnyCharacter;
@@ -75,3 +99,46 @@ impl CharacterSet for HashSet<char> {
self.contains(&ch)
}
}
+
+pub struct CharacterSetUnion<A: CharacterSet, B: CharacterSet> {
+ first: A,
+ second: B,
+}
+
+impl<A: CharacterSet, B: CharacterSet> CharacterSet for CharacterSetUnion<A, B> {
+ fn contains(&self, ch: char) -> bool {
+ self.first.contains(ch) || self.second.contains(ch)
+ }
+}
+
+pub struct CharacterSetIntersection<A: CharacterSet, B: CharacterSet> {
+ first: A,
+ second: B,
+}
+
+impl<A: CharacterSet, B: CharacterSet> CharacterSet for CharacterSetIntersection<A, B> {
+ fn contains(&self, ch: char) -> bool {
+ self.first.contains(ch) && self.second.contains(ch)
+ }
+}
+
+pub struct CharacterSetDifference<A: CharacterSet, B: CharacterSet> {
+ first: A,
+ second: B,
+}
+
+impl<A: CharacterSet, B: CharacterSet> CharacterSet for CharacterSetDifference<A, B> {
+ fn contains(&self, ch: char) -> bool {
+ self.first.contains(ch) && !self.second.contains(ch)
+ }
+}
+
+pub struct CharacterSetComplement<Inner: CharacterSet> {
+ inner: Inner,
+}
+
+impl<Inner: CharacterSet> CharacterSet for CharacterSetComplement<Inner> {
+ fn contains(&self, ch: char) -> bool {
+ !self.inner.contains(ch)
+ }
+}