fn get_links(link_nodes: Select) -> Option<String> {

        let mut rel_permalink: Option<String> = for node in link_nodes {
            link = String::from(node.value().attr("href")?);

            return Some(link);
        };

        Some(rel_permalink)
    }

This is what I’m trying to do, and I’ve been stuck with this code for an hour, I simply don’t know how to put this function togheter… Essentially I would like to take some link_nodes and just return the link String, but I’m stuck in the use of Option with the ? operator… Pheraps trying to write it with match would clear things out(?)

Also I come from JavaScript in which expressions do not have their own scope, meaning I’m having troubles to understand how to get out a variable from a for loop, should I initialize the rel_permalink variable as the for loop result?

This are the errors i get:

error[E0308]: mismatched types
  --> src/main.rs:55:49
   |
55 |           let mut rel_permalink: Option<String> = for node in link_nodes {
   |  _________________________________________________^
56 | |             link = String::from(node.value().attr("href")?);
57 | |
58 | |             return Some(link);
59 | |         };
   | |_________^ expected `Option<String>`, found `()`
   |
   = note:   expected enum `Option<String>`
           found unit type `()`
note: the function expects a value to always be returned, but loops might run zero times
  --> src/main.rs:55:49
   |
55 |         let mut rel_permalink: Option<String> = for node in link_nodes {
   |                                                 ^^^^^^^^^^^^^^^^^^^^^^ this might have zero elements to iterate on
56 |             link = String::from(node.value().attr("href")?);
   |                                                          - if the loop doesn't execute, this value would never get returned
57 |
58 |             return Some(link);
   |             ----------------- if the loop doesn't execute, this value would never get returned
   = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
  • taladar@sh.itjust.works
    link
    fedilink
    arrow-up
    0
    ·
    4 hours ago

    Your return will return from the function, not from the for loop as you probably assume. The for loop itself does not return a value. Only loop based loops can use break to return values, other loops do not.

    You also forgot the let keyword in your assignment

    I assume you want to return the value of the href attribute for the first node that has one? In that case you want something like

    fn get_first_href_value(link_nodes: Select) -> Option<String> {
            for node in link_nodes {
                if let Some(href_value) = node.value().attr("href") {
                    return Some(href_value.into());
                }
            }
    
            None
    }
    

    or, more idiomatically

    fn get_first_href_value(link_nodes: Select) -> Option<String> {
        link_nodes.into_iter().find_map(|node| node.value().attr("href")).map(|v| v.to_string())
    }
    
  • asudox@programming.dev
    link
    fedilink
    arrow-up
    0
    ·
    edit-2
    4 hours ago

    Please explain what it is you are trying to do.

    As far as I can understand from the function return value and the body of the function, you are trying to compose all of the href attributes in each node into a single String, which is encapsulated in an Option. Is this correct? Something looks weird but I can’t quite catch it. I hope you didn’t take a quick glance over the rust book and just started assuming things work like JS in Rust.

  • RustyNova@lemmy.world
    link
    fedilink
    arrow-up
    0
    ·
    edit-2
    5 hours ago

    I wouldn’t mind having a explanation of what you want to do instead of the code. It’s not quite clear what you mean.

    Anyways, what you want is to transform an iterator (your Select) into an iterator of Option<String>?

    For that, there’s multiple ways but here’s the simplest:

    link_nodes.map(|node| node.value().attr("href").to_string())

    Essentially, for each elements, we execute a closure (arrow function in JavaScript) that transform the node into your href string.

    P.S. can’t guarantee it works, I don’t know what this “Select” type is, and I’m programming on mobile