Basic questions from doing the "allergies" example on exercism.io


#1

exercism gives you practice problems. They give you tests and you make them pass. Then you chat with other users of the site about the solutions. The rust section isn’t super active and I’m not getting any comments on my rust submissions.

The “Allergies” test looks like this:

    `extern crate allergies;

    use allergies::*;

    #[test]
    fn test_no_allergies_means_not_allergic() {
        let allergies = Allergies(0);
        assert_eq!(false, allergies.is_allergic_to(&Allergen::Peanuts));
        assert_eq!(false, allergies.is_allergic_to(&Allergen::Cats));
        assert_eq!(false, allergies.is_allergic_to(&Allergen::Strawberries));
    }

    #[test]
    #[ignore]
    fn test_is_allergic_to_eggs() {
        assert_eq!(true, Allergies(1).is_allergic_to(&Allergen::Eggs));
    }`


etc...

Most of the submissions look something like this:

#[derive(PartialEq, Debug, Clone)]
pub enum Allergen {
    Eggs = 1,
    Peanuts = 2,
    Shellfish = 4,
    Strawberries = 8,
    Tomatoes = 16,
    Chocolate = 32,
    Pollen = 64,
    Cats = 128,
}

#[allow(non_snake_case)]
pub fn Allergies(score: u32) -> Allergies {
    Allergies::new(score)
}

pub struct Allergies {
    score: u32,
}

impl Allergies{
    fn new(score: u32) -> Allergies {
        Allergies {score: score}
    }

    pub fn is_allergic_to(&self, allergen: &Allergen) -> bool {
        let allergen = allergen.clone() as u32;
        allergen & self.score != 0
    }

    pub fn allergies(&self) -> Vec<Allergen> {
        use Allergen::*;

        let list = vec![Eggs, Peanuts, Shellfish, Strawberries, Tomatoes, Chocolate, Pollen, Cats];
        list.into_iter().filter(|a| self.is_allergic_to(&a)).collect()

    }
}
  • Would you really use an Enum for something like this? You can’t iterate through the keys of an Enum (without writing all the keys down somewhere else)

  • Some of the submissions defined the Allergies struct like:
    pub struct Allergies (pub i32);

Where is that form documented? I’m couldn’t figure those submissions out. Something about self.

  • Why do you need to clone the allergen value as u32 to be able to use bitwise-and it with something?

  • I feel like I shouldn’t need to derive[ all this extra stuff to do this simple little thing (loop through some numbers and & them with some input), but this is just the like 3rd little example of rust I’ve done so maybe my senses are off.

thanks!


#2

I’m just reading the style guide, and it recommends to use std::bitflags instead (though be warned that I have no experience with that).

That is a so-called tuple struct, where the two pub keywords are added for exporting the struct and the field.

You probably could just use allergen.score?

It’s not a big deal and often useful, so people might add it as a matter of course.


#3

I’m working on the same Exercism problem and had the same issue with iterating over the Enum. Someone on Twitter pointed me to this crate: http://contain-rs.github.io/enum-set/enum_set/index.html (an example can be found here: http://contain-rs.github.io/enum-set/src/enum_set/lib.rs.html#272).

It appears to allow you to directly convert an Enum to an Iterator, however I can’t figure out how to actually use it to begin with. All the test code appears to create a new (empty) EnumSet and then uses insert to add the elements of the Enum to the EnumSet…but that gets you back to the same problem of needing to manually iterate through the Enum to call insert each time. Not sure if it’s possible to just say “hey, put this whole Enum into this EnumSet thing and let’s call it good”.