#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn u64_digits(n: u64) -> usize {
if n == 0 { 1 } else { (n.ilog10() + 1) as usize }
}
pub(crate) struct Lines<'a> {
input: &'a str,
pos: usize,
}
impl<'a> Lines<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) const fn new(input: &'a str) -> Self {
Self { input, pos: 0 }
}
}
impl<'a> Iterator for Lines<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
if self.pos >= self.input.len() {
return None;
}
let bytes = &self.input.as_bytes()[self.pos..];
#[cfg(all(feature = "memchr", not(miri)))]
let found = memchr::memchr2(b'\n', b'\r', bytes);
#[cfg(any(not(feature = "memchr"), miri))]
let found = bytes.iter().position(|&b| b == b'\n' || b == b'\r');
match found {
Some(i) => {
let line = &self.input[self.pos..self.pos + i];
if bytes[i] == b'\r' && i + 1 < bytes.len() && bytes[i + 1] == b'\n' {
self.pos += i + 2;
} else {
self.pos += i + 1;
}
Some(line)
}
None => {
let line = &self.input[self.pos..];
self.pos = self.input.len();
Some(line)
}
}
}
}