Search code examples
rustkuchiki

'expected slice, found u8' error when parsing bytes with Kuchiki


I'm running into a type error when trying to do the following:

use kuchiki::parse_html;
use kuchiki::traits::*;

fn main() {
    let data = r#"<!DOCTYPE html>
                  <html>
                      <body>
                          test
                      </body>
                  </html>"#;
    let dom = parse_html()
        .from_utf8()
        .from_iter(data.as_bytes());
}

The error is:

error[E0271]: type mismatch resolving `<tendril::fmt::Bytes as tendril::fmt::SliceFormat>::Slice == u8`
  --> src/main.rs:13:10
   |
13 |         .from_iter(data.as_bytes());
   |          ^^^^^^^^^ expected slice, found u8
   |
   = note: expected type `[u8]`
              found type `u8`
   = note: required because of the requirements on the impl of `std::convert::Into<tendril::tendril::Tendril<tendril::fmt::Bytes>>` for `&u8`

data.as_bytes() returns a reference to a slice of bytes (&[u8]), so I'm confused as to where the found u8 is coming from. How do I rectify this error?

The docs for the method in question are here.


Solution

  • Use read_from() instead of from_iter(), like this:

    use kuchiki::parse_html;
    use kuchiki::traits::*;
    
    fn main() {
        let data = r#"<!DOCTYPE html>
                      <html>
                          <body>
                              test
                          </body>
                      </html>"#;
        let dom = parse_html()
            .from_utf8()
            .read_from(&mut data.as_bytes());
    }
    

    You got the compile error because from_iter() needs an iterator with item type Tendril. A Tendril is a kind of string, so the type of data would need to be something like Vec<&[u8]>, but you have &[u8].

    You can also make it work using from_iter(), but it's a bit less clear/efficient:

    use kuchiki::parse_html;
    use kuchiki::traits::*;
    
    fn main() {
        let data = r#"<!DOCTYPE html>
                      <html>
                          <body>
                              test
                          </body>
                      </html>"#;
        let dom = parse_html()
            .from_utf8()
            .from_iter(vec![data.as_bytes()]);
    }