Ryan
Ryan

Reputation: 24009

Web scraping: how to find first `span` by its text content

I'm brand new to Rust and am trying to learn about its closures.

use scraper::{ElementRef, Html, Selector};

fn findFirstSpanByTextContent<'a>(html: &'a Html, text: &'a str) -> Option<ElementRef<'a>> {
    let spans = Selector::parse("span").unwrap();
    let closure = |el: ElementRef| -> bool {
        return el.text().next().unwrap().to_string() == text.to_string();
    };
    return html.select(&spans).find(closure);
}

Currently I'm getting this error:

error[E0631]: type mismatch in closure arguments
    --> src/scraper.rs:40:37
     |
37   |     let closure = |el: ElementRef| -> bool {
     |                   ------------------------ found signature of `for<'r> fn(scraper::ElementRef<'r>) -> _`
...
40   |     return html.select(&spans).find(closure);
     |                                ---- ^^^^^^^ expected signature of `for<'r> fn(&'r scraper::ElementRef<'_>) -> _`
     |                                |
     |                                required by a bound introduced by this call

What do I need to do differently?

Upvotes: 0

Views: 393

Answers (1)

Ryan
Ryan

Reputation: 24009

I think kmdreko's comment was the key.

This works:

fn find_first_span_by_text_content<'a>(html: &'a Html, text: &'a str) -> Option<ElementRef<'a>> {
    let spans = Selector::parse("span").unwrap();
    let element_option = html.select(&spans).find(|&el| {
        let first_text_option = el.text().next();
        if first_text_option.is_none() {
            return false;
        } else {
            return first_text_option.unwrap().to_string() == text.to_string();
        }
    });

    return element_option;
}

Upvotes: 3

Related Questions