#[derive(Clone, Debug)] enum Flow { Every, Once, End } use Flow::*; #[derive(Clone, Debug)] struct Verse { animal: String, flow_type: Flow, aside: String, } impl Verse { pub fn new(animal: &str, flow_type: Flow, aside: &str) -> Verse { Verse { animal: String::from(animal), flow_type, aside: String::from(aside) } } } fn swallowed_a(verse: &Verse) { println!("\nThere was an old lady who swallowed a {};\n{}", verse.animal, verse.aside); } fn cumulative_refrain(slice: &[Verse]) { for n in 0..slice.len() { let repeat = &slice[n]; if n != (slice.len() - 1) { let prev = &slice[n + 1]; println!("\tShe swallowed the {} to catch the {};", repeat.animal, prev.animal); if let Every = prev.flow_type { println!("\t{}", prev.aside); } } } } fn print_verses(animals: [Verse;8]) { for index in 0..animals.len() { let verse = &animals[index]; swallowed_a(&verse); // End early on the last verse if let End = verse.flow_type { return }; if index > 0 { let slice = &animals[0..=index]; let mut slice = slice.to_vec(); slice.reverse(); cumulative_refrain(&slice); } } } fn main() { let animals = [ Verse::new("fly", Every, "I don't know why she swallowed a fly - perhaps she'll die!"), Verse::new("spider", Every, "That wriggled and jiggled and tickled inside her!"), Verse::new("bird", Once, "How absurd to swallow a bird!"), Verse::new("cat", Once, "Imagine that! She swallowed a cat!"), Verse::new("dog", Once, "What a hog, to swallow a dog!"), Verse::new("goat", Once, "She just opened her throat and swallowed a goat!"), Verse::new("cow", Once, "I don't know how she swallowed a cow!"), Verse::new("horse", End, "She's dead of course!"), ]; print_verses(animals); }