How to use slice, len on AsRef<[u8]> generic?

I am trying to write a flexible function that will accept anything that can provide a &[u8] reference — for example, the &[u8], &str and String types.

In the function I need to do things like take a slice, find a length, etc. I'm clearly missing some necessary trait bounds.

The compiler suggests ExactSizeIterator to implement len(), but then changes its mind when I add it. (So fickle!) I also tried adding the bound Index<Range<usize>, Output=T> to get the slice to work, but that also didn't work.

I'm a new to Rust, so any help is appreciated.

use std::fmt::Debug;
//use std::ops::{Index, Range};
//use std::iter::ExactSizeIterator;


fn decode<T>(buf: T)
    where T: AsRef<[u8]> + Debug
{
    // println!("{:?}", buf);  // this works
    if buf.len() > 4 {
        let subset = buf[2..4];
        println!("{:?} {}", subset, subset.len());
    }
}

fn main() {
    decode(b"byte array");
    decode("static string literal");
    decode("string".to_string());
    
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `len` found for type parameter `T` in the current scope
  --> src/main.rs:10:12
   |
6  | fn decode<T>(buf: T)
   |           - method `len` not found for this type parameter
...
10 |     if buf.len() > 4 {
   |            ^^^ method not found in `T`
   |
   = help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `len`, perhaps you need to restrict type parameter `T` with it:
   |
7  |     where T: AsRef<[u8]> + Debug + ExactSizeIterator
   |                                  +++++++++++++++++++

error[E0608]: cannot index into a value of type `T`
  --> src/main.rs:11:22
   |
11 |         let subset = buf[2..4];
   |                      ^^^^^^^^^

Some errors have detailed explanations: E0599, E0608.
For more information about an error, try `rustc --explain E0599`.
error: could not compile `playground` due to 2 previous errors

In order to use the AsRef trait, you need to call the as_ref method. For example: Rust Playground

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.