mirror of https://github.com/astral-sh/uv
51 lines
1.5 KiB
Rust
51 lines
1.5 KiB
Rust
/// A simple splitter that uses `memchr` to find the next delimiter.
|
|
pub(crate) struct MemchrSplitter<'a> {
|
|
memchr: memchr::Memchr<'a>,
|
|
haystack: &'a str,
|
|
offset: usize,
|
|
}
|
|
|
|
impl<'a> MemchrSplitter<'a> {
|
|
#[inline]
|
|
pub(crate) fn split(haystack: &'a str, delimiter: u8) -> Self {
|
|
Self {
|
|
memchr: memchr::Memchr::new(delimiter, haystack.as_bytes()),
|
|
haystack,
|
|
offset: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Iterator for MemchrSplitter<'a> {
|
|
type Item = &'a str;
|
|
|
|
#[inline(always)]
|
|
#[allow(clippy::inline_always)]
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
match self.memchr.next() {
|
|
Some(index) => {
|
|
let start = self.offset;
|
|
self.offset = index + 1;
|
|
Some(&self.haystack[start..index])
|
|
}
|
|
None if self.offset < self.haystack.len() => {
|
|
let start = self.offset;
|
|
self.offset = self.haystack.len();
|
|
Some(&self.haystack[start..])
|
|
}
|
|
None => None,
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
// We know we'll return at least one item if there's remaining text.
|
|
let min = usize::from(self.offset < self.haystack.len());
|
|
|
|
// Maximum possible splits is remaining length divided by 2 (minimum one char between delimiters).
|
|
let max = (self.haystack.len() - self.offset + 1) / 2 + min;
|
|
|
|
(min, Some(max))
|
|
}
|
|
}
|