Skip Navigation

User banner
Posts
0
Comments
10
Joined
3 yr. ago

  • @dontblink It feels like you should never OsResponseType::Bool(true) so you could probably encode that in the enum just as the same Unrecognised

       
        
    enum OsResponseType {  
     Message { message: String },  
     Unrecognised  
    }  
    
      
  • @dontblink e.g.

       
        
    enum OsResponseType {  
     Message { message: String },  
     Bool(bool),  
    }
    
    fn find\_os(os: OperativeSystem) -\> OsResponseType {  
     match os {  
     OperativeSystem::Linux =\> OsResponseType::Message {  
     message: "This pc uses Linux".into(),  
     },  
     OperativeSystem::Windows =\> OsResponseType::Bool(false),  
     OperativeSystem::Mac =\> OsResponseType::Bool(true),  
     \_ =\> OsResponseType::Bool(false),  
     }  
    }  
      
    
      

    Note the logic here is nonsense

  • @dontblink

       
        
    enum OperativeSystem {  
     Linux,  
     Windows,  
     Mac,  
     Unrecognised,  
    }
    
    fn find\_os(os: OperativeSystem) -\> String {  
     match os {  
     OperativeSystem::Linux =\> "This pc uses Linux".into(),  
     OperativeSystem::Windows =\> "This pc uses Windows, unlucky you!".into(),  
     OperativeSystem::Mac =\> "This pc uses Mac, I'm really sorry!".into(),  
     \_ =\> "unrecognised".into(),  
     }  
    }  
      
    
      

    If you want to return either a Boolean or a String you can introduce an enum

  • @dontblink The idea of the iterator is to assemble all of your computation lazily and only perform it at the final step. In this case you don't actually perform any the actions until you call collect, which essentially creates a loop that goes through the original Select and performs the calculations and pushes the results to a Vec.

  • @dontblink For stuff like this, I tend to prefer rusts iterator combinators, but I admit it's a bit more advanced. So in this case you'd do

       
        
    fn get\_links(link\_nodes: scraper::html::Select\<'\_, '\_\>) -\> Vec\<String\> {  
     link\_nodes  
     .into\_iter() // convert select to iterator  
     .filter\_map(|node| node.value().attr("href")) // only select nodes with an href attribute, and select that value  
     .map(ToString::to\_string) // map that value to a string  
     .collect()  
    }
    
    
      
  • @dontblink Yeah, I think it makes sense to use match as a beginner just to understand what is going on. In the end the x? just desugars to

       
        
    match x {  
     Some(value) =\> value,  
     None =\> return None  
    }  
      
    
      

    for options an

       
        
    match x {  
     Ok(value) =\> value,  
     Err(err) =\> return Err(err.into())  
    }  
      
    
      

    for results, where that .into() converts the error type into the return type of function.

  • @dontblink If you really want to do it in a loop, you could do something like

       
        
    fn get\_links(link\_nodes: Select) -\> Option\<String\> {  
     let mut rel\_permalink: Option\<String\> = None;  
     for node in link\_nodes {  
     if let Some(link) = node.value().attr("href")? {  
     rel\_permalink = Some(String::from(link));  
     break  
     }  
     };  
     rel\_permalink  
    }  
      
    
      

    That said, your function name suggest you want all links, so some kind of collection of links. Is this the case?

  • @dontblink Looks like there's some weird stuff between my instance and yours in the formatting. There shouldn't be any backslashes anywhere

  • @dontblink Here's a little explanation for the methods
    into\_iter : converts Select into an iterator (a for loop does this implicitly)
    filter\_map: takes an iterator and constructs an iterator from an Fn(T) -\> Option\<S\> where the emitted elements are the elements for which applying the function/closure is Some
    next: takes the next element of the iterator as an Option.

  • @dontblink It's a little unclear what you want to do. It looks like Select implements into iterator. As far as I can parse your code you want to get the first node with a href element. In that case you should do:

       
        
    link\_nodes.into\_iter().filter\_map(|node| node.value().attr("href")).map(String::from).next()