In this exercise we will implement a Rust-y, simpler variant of Pig Latin

You will learn:

  • How to create a Rust library

  • How to deal with Strings and splitting

  • How to deal with char of a String

  • An early taste of Iterators

  • How to define Globals

  • Arrays vs Vectors

  • See Rust compiler’s type inference in action

  • Most common way to do string concatenation

Specification

For this exercise we define

  • the Vowels of English alphabet → ['a', 'e', 'i', 'o', 'u']

  • a sentence is a collection of ASCII characters with words that are separated by a white space

For any given sentence, you have to modify each word of the sentence using the following logic:

  • If the word begins with a vowel → add prefix “sr” to the word

  • If the word does not begin with a vowel → add suffix “rs” to the word

Tasks

Step 1

Create a new lib and name it rustlatin.

Click to see the solution
cargo new --lib rustlatin

Step 2

Create a global variable in the file that defines the Vowels as specified above

Click to see the solution
const VOWELS: [char; 5] = ['a', 'e', 'i', 'o', 'u'];

Step 3

Copy paste this skeleton of the function

fn rustlatin(sentence: String) -> String {
    unimplemented!()
}
Click to see the sample solution
fn rustlatin(sentence: &str) -> String {
    let mut new_words = Vec::new();
    for word in sentence.split(' ') {
        let first_char_of_word = word.chars().next().unwrap();
        if VOWELS.contains(&first_char_of_word) {
            new_words.push("sr".to_string() + word);
        } else {
            new_words.push(word.to_string() + "rs");
        }
    }

    new_words.join(" ")
}

Step 4

Add tests

Click to see the hints/solutions for tests
#[test]
fn correct_translation() {
    // Why can we compare `&str` and `String` here?
    // https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3C%26%27a%20str%3E
    assert_eq!(
        "rustrs helpsrs yours sravoid sra lotrs srof srirritating bugsrs",
        rustlatin("rust helps you avoid a lot of irritating bugs")
    )
}

#[test]
fn incorrect() {
    assert_ne!(
        "this shouldrs not workrs",
        rustlatin("this should not work")
    )
}

Step 5 (optional)

If not already done, use functional techniques (i.e. methods on iterators) to write the same function. Test this new function as well.

Click to see hints/solutions for this step
fn rustlatin_match(sentence: &str) -> String {
    // transform incoming words vector to rustlatined outgoing
    let new_words: Vec<_> = sentence
        .split(' ')
        .into_iter()
        .map(|word| {
            let first_char_of_word = word.chars().next().unwrap();
            if VOWELS.contains(&first_char_of_word) {
                "sr".to_string() + word
            } else {
                word.to_string() + "rs"
            }
        })
        .collect();

    new_words.join(" ")
}