I have a function that takes a slice of bytes and a search depth. I want to start at the end of slice and search for the first newline. Then return everything that appears after that new line as new byte slice over the original. For example:
This is a line\n and this is a another line \n this is ano
this should return a byte slice containing this is ano
This is my attempt using iter.
let pos = buf.iter().rev().take(search_depth).rposition(|b| *b == b'\n')?;
Some(buf[pos..])
However, it does not work correctly. I also tried position(). This function will be called a lot, so I am trying to do it as efficiently as possible while avoiding collecting into a Vec. Any ideas?
You're reversing the iterator and then effectively reversing the position again with rposition. You just need to use position and then invert the returned index to use on the buffer.
fn search(buf: &[u8], search_depth: usize) -> Option<&[u8]> {
let pos = buf
.iter()
.rev()
.take(search_depth)
.position(|b| *b == b'\n')?;
let found = &buf[buf.len() - pos..];
println!("{:?}", std::str::from_utf8(found));
Some(found)
}
fn main() {
let buf = b"This is a line\n and this is a another line \n this is ano";
assert_eq!(search(buf, 100), Some(b" this is ano".as_slice()));
assert_eq!(search(&buf[..=18], 100), Some(b" and".as_slice()));
assert_eq!(search(buf, 17), Some(b" this is ano".as_slice()));
}
There may still be an edge case that's not accounted for there, I'm not entirely sure.