gigapixel

joined 2 years ago
[–] [email protected] 1 points 2 weeks ago (1 children)

@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  
}  
[–] [email protected] 0 points 2 weeks ago (2 children)

@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

[–] [email protected] 0 points 2 weeks ago* (last edited 2 weeks ago) (3 children)

@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

[–] [email protected] 0 points 2 weeks ago (4 children)

@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.

[–] [email protected] 0 points 2 weeks ago (5 children)

@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()  
}

[–] [email protected] 0 points 2 weeks ago (6 children)

@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.

[–] [email protected] 0 points 2 weeks ago* (last edited 2 weeks ago) (11 children)

@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?

[–] [email protected] 0 points 2 weeks ago (12 children)

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

[–] [email protected] 0 points 2 weeks ago (13 children)

@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.

[–] [email protected] 0 points 2 weeks ago (14 children)

@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()