-
-
Save rust-play/6f4932a58832875b81e37306cf6f16cd to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub trait Pattern<T: ?Sized>: Sized { | |
type Searcher: Search<T>; | |
fn into_searcher(self) -> Self::Searcher; | |
fn search(self, haystack: &T) -> SearchSteps<'_, Self::Searcher, T> { | |
self.into_searcher().search(haystack) | |
} | |
fn search_back(self, haystack: &T) -> SearchStepsBack<'_, Self::Searcher, T> | |
where Self::Searcher: SearchBack<T> | |
{ | |
self.into_searcher().search_back(haystack) | |
} | |
} | |
// Safety requirements | |
// | |
// The safety requirements are determined by the type `T` | |
// | |
// For `str`: | |
// - `start` and `end` of `SearchStep` returned by `step` | |
// are both on a utf-8 code point boundary within haystack | |
pub unsafe trait Search<T: ?Sized>: Sized { | |
fn step(&mut self, haystack: &T) -> Option<SearchStep>; | |
fn search(self, haystack: &T) -> SearchSteps<'_, Self, T> { | |
SearchSteps { haystack, searcher: self } | |
} | |
} | |
// Safety requirements | |
// | |
// The safety requirements are determined by the type `T` | |
// | |
// For `str`: | |
// - `start` and `end` of `SearchStep` returned by `step_back` | |
// are both on a utf-8 code point boundary within haystack | |
pub unsafe trait SearchBack<T: ?Sized>: Search<T> { | |
fn step_back(&mut self, haystack: &T) -> Option<SearchStep>; | |
fn search_back(self, haystack: &T) -> SearchStepsBack<'_, Self, T> { | |
SearchStepsBack { haystack, searcher: self } | |
} | |
} | |
pub struct SearchStep { | |
pub matches: bool, | |
pub start: usize, | |
pub end: usize, | |
} | |
pub struct SearchSteps<'a, S, T: ?Sized> { | |
haystack: &'a T, | |
searcher: S, | |
} | |
impl<'a, S: Search<T>, T: ?Sized> Iterator for SearchSteps<'a, S, T> { | |
type Item = SearchStep; | |
fn next(&mut self) -> Option<SearchStep> { | |
self.searcher.step(self.haystack) | |
} | |
} | |
pub struct SearchStepsBack<'a, S, T: ?Sized> { | |
haystack: &'a T, | |
searcher: S, | |
} | |
impl<'a, S: SearchBack<T>, T: ?Sized> Iterator for SearchStepsBack<'a, S, T> { | |
type Item = SearchStep; | |
fn next(&mut self) -> Option<SearchStep> { | |
self.searcher.step_back(self.haystack) | |
} | |
} | |
// For example: | |
pub fn str_contains(s: &str, pat: impl Pattern<str>) -> bool { | |
pat.search(s).any(|step| step.matches) | |
} | |
pub fn slice_contains<T>(s: &[T], pat: impl Pattern<[T]>) -> bool { | |
pat.search(s).any(|step| step.matches) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment