Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to apply function that returns Result to each element of HashSet in Rust?

I have a type defined as follows:

pub struct State<T: Clone + Eq> {
    pub db: HashSet<T>,
}

And I have a function that looks like the following:

fn check(&self) -> Result<(), Error> {
   self.db.iter().for_each(|elem| elem.check());
   Ok(())
}

So I want to call check function for each of the element in HashSet. I just want to ensure that either all return () or there is some Error thrown. The above throws error as it expect () as output of elem.check(), but it returns Result. What’s the proper way to handle this in Rust?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Since (): FromIterator<()>, it’s actually quite ergonomic to short-circuit “collect” multiple Result<(), E> into another Result<(), E>:

use std::collections::HashSet;
pub struct State<T: Clone + Eq> {
    pub db: HashSet<T>,
}

/// Checks for equality to 0
fn check(x: i32) -> Result<String, String> {
    if x == 0 {
        Ok("yay, got 0".into())
    } else {
        Err(format!("whoops, got {} != 0", x))
    }
}

impl State<i32> {
    fn check(&self) -> Result<(), String> {
        self.db
            .iter()
            .map(|elem| check(*elem).map(|_| ()))
            .collect()
    }
}

fn main() {
    let state1 = State {
        db: [0, 0, 0].into(),
    };
    let state2 = State {
        db: [0, 1, 2].into(),
    };

    println!("{:?}, {:?}", state1.check(), state2.check());
    // Ok(()), Err("whoops, got 1 != 0")
}

but it’s not clear what advantage this offers over the imperative solution, which is much clearer.

impl State<i32> {
    fn check(&self) -> Result<(), String> {
        for x in &self.db {
            check(*x)?;
        }
        Ok(())
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading