Yes, I know this exercise has been posted before, but I'm posting it again because I want feedback on why certain parts of my code aren't idiomatic. I'm new to rust, and my code works, but as I said, I'd like to have parts pointed out that could be implemented another way, and why my way is "wrong". Thx in advance!
I haven't given naming that much of a thought, many variables could probably be named better. I could also extract a lot of parts into their own functions, however I'm more gunning for advice on which kind of patterns are applicable to my solution, rather than how I could modularize my code more by simple extraction. I'm also not looking for "This is the best solution for this problem", I'm looking for "this part is 'wrong/unsafe/stupid' because of X, here is how to do it better".
pub fn pig_latinize(text: String) -> String {
let allowed_specials = ['.', ',', '?', '!'];
text.split_whitespace()
.map(|word_with_special_char| {
let annoying_character = allowed_specials
.iter()
.any(|special| word_with_special_char.ends_with(special.to_string().as_str()));
let mut suffix = "";
let word = if annoying_character {
let (word_without_special_char, special_char) = word_with_special_char
.split_at(word_with_special_char.len() - 1);
suffix = special_char;
word_without_special_char
} else {
word_with_special_char
}
.to_string();
pig_latin_single_word(word) + suffix
})
.collect::<Vec<_>>()
.join(" ")
}
fn pig_latin_single_word(word: String) -> String {
let mut word = word.clone();
let vowels = "aeiou".to_string();
let first_letter = word.remove(0);
let is_uppercase = first_letter.is_uppercase();
let mut lower_first_letter = first_letter.to_lowercase().to_string();
if vowels.contains(lower_first_letter.as_str()) {
word.insert(0, first_letter.clone());
lower_first_letter = "h".to_string();
}
word.push_str(format!("-{}ay", lower_first_letter).as_str());
if is_uppercase {
let first_letter = word.remove(0);
word.insert(0, first_letter.to_string().to_uppercase().remove(0));
}
word
}
Tests:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pig_latin() {
let input = "This is a very complicated sentence. It is actually more than one sentence.".to_string();
let expected = "His-tay is-hay a-hay ery-vay omplicated-cay entence-say. It-hay is-hay actually-hay ore-may han-tay one-hay entence-say.".to_string();
let actual = pig_latinize(input);
assert_eq!(actual, expected);
}
#[test]
fn test_pig_latin_multiple_words() {
let input = "This is a very complicated sentence".to_string();
let expected = "His-tay is-hay a-hay ery-vay omplicated-cay entence-say".to_string();
let actual = pig_latinize(input);
assert_eq!(actual, expected);
}
#[test]
fn test_pig_latin_small1() {
let input = "This".to_string();
let expected = "His-tay".to_string();
let actual = pig_latin_single_word(input);
assert_eq!(actual, expected);
}
#[test]
fn test_pig_latin_small2() {
let input = "this".to_string();
let expected = "his-tay".to_string();
let actual = pig_latin_single_word(input);
assert_eq!(actual, expected);
}
#[test]
fn test_pig_latin_small3() {
let input = "one".to_string();
let expected = "one-hay".to_string();
let actual = pig_latin_single_word(input);
assert_eq!(actual, expected);
}
}
```