user8370684
user8370684

Reputation:

How to compare a slice with a vector in Rust?

How do I compare an array slice with a vector in Rust? The code in question:

fn parse<R: io::Read>(reader: R, fixed: &[u8]) -> io::Result<bool> {
    let mut buf = vec![0; fixed.len()];
    match reader.read(&mut buf) {
        Ok(n) => Ok(n == fixed.len() && fixed == &mut buf),
        Err(e) => Err(e)
    }
}

The error that I get:

error[E0277]: the trait bound `[u8]: std::cmp::PartialEq<std::vec::Vec<u8>>` is not satisfied
  --> src/main.rs:32:47
   |
32 |         Ok(n) => Ok(n == fixed.len() && fixed == &mut buf),
   |                                               ^^ can't compare `[u8]` with `std::vec::Vec<u8>`
   |
   = help: the trait `std::cmp::PartialEq<std::vec::Vec<u8>>` is not implemented for `[u8]`

The answer must be simple but it is eluding me.

Upvotes: 8

Views: 9623

Answers (1)

Shepmaster
Shepmaster

Reputation: 432089

As the error message states:

the trait std::cmp::PartialEq<std::vec::Vec<u8>> is not implemented for [u8]

However, the opposite direction is implemented:

Ok(n) => Ok(n == fixed.len() && buf == fixed),

Additionally, you will need to mark your parameter as mutable: mut reader: R.

Read::read_exact performs the n == fixed.len() check for you.

Allocating a vector full of zeroes is not as efficient as it could be. You could instead limit the input and read into a vector, allocating as you go:

fn parse<R>(reader: R, fixed: &[u8]) -> io::Result<bool>
where
    R: Read,
{
    let mut buf = Vec::with_capacity(fixed.len());
    reader
        .take(fixed.len() as u64)
        .read_to_end(&mut buf)
        .map(|_| buf == fixed)
}

The implementation of equality for slices already compares the lengths of the two sides, so I've also removed that, while switching to using combinators.

Upvotes: 8

Related Questions