Just finished an exercise in the Rust online book and I wanted to know if there is anything worth talking about in the code I wrote... if there's any mistake or optimization possible.

Convert strings to pig latin

  • The first consonant of each word is moved to the end of the word and “ay” is added, so “first” becomes “irst-fay”.

  • Words that start with a vowel have “hay” added to the end instead (“apple” becomes “apple-hay”).

  • Keep in mind the details about UTF-8 encoding!

use std::io;
fn main() {
    let mut user_input = String::new();
        .read_line(&mut user_input)
        .expect("Failed to read line.");
    for word in user_input.split_whitespace() {
        match word.chars().nth(0).unwrap() {
            'a' | 'e' | 'i' | 'o' | 'u' | 'y' => print!("{} ", format!("{}-hay", word.trim())),
            _ => print!("{} ", format!("{}{}-ay", &word[word.chars().next().unwrap().len_utf8()..].trim(), word.chars().nth(0).unwrap())),
  • 2
    \$\begingroup\$ Welcome to Code Review! Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers. \$\endgroup\$
    – Vogel612
    Commented Jul 4, 2020 at 15:40

1 Answer 1


Some small remarks:

  • according to the documentation, you want to output irst-fay on first, but your code will output irstf-ay instead

  • your code will only work on lower case words, but not on "Apple"

  • instead of print!("{} ", format!(...)) use print!(...)

  • instead of nth(0) use next()

  • I recommend you to format your code with rustfmt

  • instead of &word[word.chars().next().unwrap().len_utf8()..] you can use c.len_utf8() if you name your match instead of using _, e.g.

    match word.chars().nth(0).unwrap() {
         'a' | 'e' | 'i' | 'o' | 'u' | 'y' => print!("{}-hay ", word.trim())),
          c => print!("{}-{}ay ", &word[c.len_utf8()..].trim(), c),
  • if you know that your index will end up at a proper UTF8 boundary you can use &word[1..] and &word[..1] instead of your indexing, but your variant is a lot safer. Well done here, as invalid string slicing is a common error in first Rust experiences :)

  • \$\begingroup\$ Thank you very much ! I've updated the code on my machine and passed it trough rustfmt once again and also fixed it so it supports uppercase and lowercase :D \$\endgroup\$
    – h4k
    Commented Jun 28, 2020 at 19:17
  • \$\begingroup\$ @h4k that sounds great!. As a further exercise, write fn piglatin(input : &str) -> String (or a similar function) and additional tests as in Chapter 11. Don't worry about jumping over chapter 9 and 10, both aren't necessary to write simple tests :). The first and Apple test cases should both be covered, as well as an empty string. \$\endgroup\$
    – Zeta
    Commented Jun 29, 2020 at 7:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.