75 lines
2.0 KiB
Rust
75 lines
2.0 KiB
Rust
#[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);
|
|
}
|