Skip to content

Instantly share code, notes, and snippets.

@GlenDC
Created April 23, 2021 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GlenDC/23ed33188bca3b3ee79f0cd57a0a6c85 to your computer and use it in GitHub Desktop.
Save GlenDC/23ed33188bca3b3ee79f0cd57a0a6c85 to your computer and use it in GitHub Desktop.
Educative fun Rust snippets.
use std::io;
use std::str::FromStr;
const MAX_VERSE_COUNT: usize = 12;
const NUMBER_WORDS: [&str; MAX_VERSE_COUNT] = [
"a", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve",
];
const NUMBER_COUNT_WORDS: [&str; MAX_VERSE_COUNT] = [
"first", "second", "third", "fourth", "fifth", "sixth",
"seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth",
];
const ITEMS: [&str; MAX_VERSE_COUNT] = [
"partridge", "turtle doves", "French Hens", "calling birds",
"gold rings", "geese a laying", "swans a swimming",
"maids a milking", "ladies dancing", "lords a leaping",
"pipers piping", "drummers drumming",
];
fn upper_str(s: &str) -> String {
let mut c = s.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
}
}
fn fetch_input<T: FromStr>(question: &str) -> T {
loop {
let mut input = String::new();
println!("{}", question);
match io::stdin().read_line(&mut input) {
Ok(_) => (),
Err(msg) => {
println!("failed to read from STDIN: {}", msg);
continue;
},
};
return match input.trim().parse::<T>() {
Ok(r) => r,
Err(_) => {
println!("failed to parse input '{}'", input.trim());
continue;
},
};
}
}
fn main() {
let verse_count: u8 = {
let mut n: u8;
loop {
n = fetch_input("How many verses would you like (min 1, max 12)?");
if n >= 1 && n <= MAX_VERSE_COUNT as u8 {
break;
}
println!("Invalid verse count given....");
}
n
};
println!("Generating your christmas carol with {} verse(s):", verse_count);
println!("");
for verse in 0..verse_count {
println!("On the {} day of Christmas my true love gave to me",
upper_str(NUMBER_COUNT_WORDS[verse as usize]));
for i in 0..verse+1 {
let mut count_word = String::from_str(NUMBER_WORDS[(verse -i ) as usize]).expect("failed to turn into String");
if i == 0 {
count_word = upper_str(&count_word);
}
print!("{} {}{}",
count_word, ITEMS[(verse - i) as usize],
if i == verse { " in a tree" } else { "" });
if i != verse {
print!("{}", if i < verse-1 { "," } else { " and" });
let mut u = i;
if (verse+1)%2 == 1 {
if u < 2 {
print!(" ");
continue;
} else if u == 2 {
print!("\r\n");
continue;
}
u -= 3;
}
if u%2 == 1 {
print!("\r\n");
} else {
print!(" ");
}
}
}
println!("\r\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment