about summary refs log tree commit diff
path: root/src/libcore/str/pattern.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore/str/pattern.rs')
-rw-r--r--src/libcore/str/pattern.rs86
1 files changed, 75 insertions, 11 deletions
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 2b77d877cf4..501fc27b376 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -17,16 +17,16 @@ use super::CharEq;
 
 pub trait Pattern<'a>: Sized {
     type Searcher: Searcher<'a>;
-    fn into_matcher(self, haystack: &'a str) -> Self::Searcher;
+    fn into_searcher(self, haystack: &'a str) -> Self::Searcher;
 
     #[inline]
     fn is_contained_in(self, haystack: &'a str) -> bool {
-        self.into_matcher(haystack).next_match().is_some()
+        self.into_searcher(haystack).next_match().is_some()
     }
 
     #[inline]
     fn match_starts_at(self, haystack: &'a str, idx: usize) -> bool {
-        let mut matcher = self.into_matcher(haystack);
+        let mut matcher = self.into_searcher(haystack);
         loop {
             match matcher.next() {
                 SearchStep::Match(i, _) if i == idx => return true,
@@ -42,7 +42,7 @@ pub trait Pattern<'a>: Sized {
     #[inline]
     fn match_ends_at(self, haystack: &'a str, idx: usize) -> bool
     where Self::Searcher: ReverseSearcher<'a> {
-        let mut matcher = self.into_matcher(haystack);
+        let mut matcher = self.into_searcher(haystack);
         loop {
             match matcher.next_back() {
                 SearchStep::Match(_, j) if idx == j => return true,
@@ -115,9 +115,11 @@ pub unsafe trait ReverseSearcher<'a>: Searcher<'a> {
 
 pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {}
 
-// Impl for CharEq
+// Impl for a CharEq wrapper
 
-pub struct CharEqSearcher<'a, C> {
+struct CharEqPattern<C: CharEq>(C);
+
+pub struct CharEqSearcher<'a, C: CharEq> {
     char_eq: C,
     haystack: &'a str,
     char_indices: super::CharIndices<'a>,
@@ -125,15 +127,15 @@ pub struct CharEqSearcher<'a, C> {
     ascii_only: bool,
 }
 
-impl<'a, C: CharEq> Pattern<'a> for C {
+impl<'a, C: CharEq> Pattern<'a> for CharEqPattern<C> {
     type Searcher = CharEqSearcher<'a, C>;
 
     #[inline]
-    fn into_matcher(self, haystack: &'a str) -> CharEqSearcher<'a, C> {
+    fn into_searcher(self, haystack: &'a str) -> CharEqSearcher<'a, C> {
         CharEqSearcher {
-            ascii_only: self.only_ascii(),
+            ascii_only: self.0.only_ascii(),
             haystack: haystack,
-            char_eq: self,
+            char_eq: self.0,
             char_indices: haystack.char_indices(),
         }
     }
@@ -203,7 +205,7 @@ impl<'a, 'b> Pattern<'a> for &'b str {
     type Searcher = StrSearcher<'a, 'b>;
 
     #[inline]
-    fn into_matcher(self, haystack: &'a str) -> StrSearcher<'a, 'b> {
+    fn into_searcher(self, haystack: &'a str) -> StrSearcher<'a, 'b> {
         StrSearcher {
             haystack: haystack,
             needle: self,
@@ -293,3 +295,65 @@ where F: FnOnce(&mut StrSearcher) -> SearchStep,
         SearchStep::Done
     }
 }
+
+macro_rules! associated_items {
+    ($t:ty, $s:ident, $e:expr) => {
+        // FIXME: #22463
+        //type Searcher = $t;
+
+        fn into_searcher(self, haystack: &'a str) -> $t {
+            let $s = self;
+            $e.into_searcher(haystack)
+        }
+
+        #[inline]
+        fn is_contained_in(self, haystack: &'a str) -> bool {
+            let $s = self;
+            $e.is_contained_in(haystack)
+        }
+
+        #[inline]
+        fn match_starts_at(self, haystack: &'a str, idx: usize) -> bool {
+            let $s = self;
+            $e.match_starts_at(haystack, idx)
+        }
+
+        // FIXME: #21750
+        /*#[inline]
+        fn match_ends_at(self, haystack: &'a str, idx: usize) -> bool
+        where $t: ReverseSearcher<'a> {
+            let $s = self;
+            $e.match_ends_at(haystack, idx)
+        }*/
+    }
+}
+
+// CharEq delegation impls
+
+impl<'a, 'b> Pattern<'a> for &'b [char] {
+    type Searcher =   <CharEqPattern<Self> as Pattern<'a>>::Searcher;
+    associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
+                      s, CharEqPattern(s));
+}
+
+impl<'a> Pattern<'a> for char {
+    type Searcher =   <CharEqPattern<Self> as Pattern<'a>>::Searcher;
+    associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
+                      s, CharEqPattern(s));
+}
+
+impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool {
+    type Searcher =   <CharEqPattern<Self> as Pattern<'a>>::Searcher;
+    associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
+                      s, CharEqPattern(s));
+}
+
+// Deref-forward impl
+
+use ops::Deref;
+
+impl<'a, 'b, P: 'b + ?Sized, T: Deref<Target = P> + ?Sized> Pattern<'a> for &'b T where &'b P: Pattern<'a> {
+    type Searcher =   <&'b P as Pattern<'a>>::Searcher;
+    associated_items!(<&'b P as Pattern<'a>>::Searcher,
+                      s, (&**s));
+}