I am trying to do something simple. In a slice of u8, I want to find occurrence of two characters "\r\n". However, I cannot convert that slice into String using from_utf8 because parts of slice after "\r\n" may not be utf-8 and as far as possible I don't want to use from_utf8_unchecked. So I tried something like following.
fn find_crlf(text: &[u8]) -> Option<usize> {
let mut textiter = text.iter().peekable();
for (idx, &elem) in textiter.enumerate() {
if Some(&elem) == Some(&b'\r') {
if textiter.peek() == Some(&&b'\n') {
return Some(idx);
}
}
}
None
}
And I get following compilation errors, understandably. However I am not too sure how to go about doing this. If it were a str, it was simply .find("\r\n").
Compilation Error ->
error[E0382]: borrow of moved value: `textiter`
--> src/lib.rs:6:16
|
2 | let mut textiter = text.iter().peekable();
| ------------ move occurs because `textiter` has type `std::iter::Peekable<std::slice::Iter<'_, u8>>`, which does not implement the `Copy` trait
3 |
4 | for (idx, &elem) in textiter.enumerate() {
| -------- value moved here
5 | if Some(&elem) == Some(&b'\r') {
6 | if textiter.peek() == Some(&&b'\n') {
| ^^^^^^^^ value borrowed here after move
May be I am missing something really simple, but stuck on this for quite some time now.
Usually, the best way to write this sort of code is to not use
Peekableat all. It's a tricky API to use because you often want to callpeekwhen you are in the middle of iterating, which usually means you have already borrowed the iterator mutably so you can't borrow it again.But, since you asked about
Peekablespecifically, you could rewrite your code to explicitly callnextin a loop, which is often the only way to usepeek:Generally, a better method for look-ahead is to use
slice::windowsortuple_windowsfromitertools.Given that your input is a slice, you can use
slice::windows:In general though, I prefer the syntax of the
itertoolsmethod, because you can pattern match on the tuple which feels cleaner than indexing into a slice:Or, even better: