pub fn words_with_commas (words: &[&str]) -> String {
add_commas(words, false)
}
pub fn words_with_oxford_commas (words: &[&str]) -> String {
add_commas(words, true)
}
fn add_commas (words: &[&str], do_oxford: bool) -> String {
let mut result = "".to_string();
let mut word = 0;
while word < words.len() {
result.push_str(words[word]);
if words.len() - word > 2 {
result.push_str(", ");
} else if words.len() - word == 2 {
if do_oxford && words.len() >= 3 {
result.push_str(",");
}
result.push_str(" and ");
}
word += 1;
}
result
}
pub fn word_wrap (text: &str, width: usize) -> Vec<String> {
let mut lines : Vec<String> = vec![];
let mut words : Vec<&str> = text.split(char::is_whitespace).collect();
let mut line_length = 0;
let mut line = "".to_string();
while !words.is_empty() {
let word = words[0];
if word.len() == 0 { words.remove(0);
continue;
}
if line_length + word.len() > width {
if line.len() == 0 { lines.push(word.to_string());
words.remove(0);
} else { lines.push(line);
}
line_length = 0;
line = "".to_string ();
} else { line_length += 1 + word.len();
if line.len() > 0 {
line.push_str(" ");
}
line.push_str(word);
words.remove(0);
}
}
if line.len() > 0 {
lines.push(line);
}
lines
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_words_with_commas () {
assert_eq!("", words_with_commas(&[]));
assert_eq!("a", words_with_commas(&["a"]));
assert_eq!("a and b", words_with_commas(&["a", "b"]));
assert_eq!("a, b and c", words_with_commas(&["a", "b", "c"]));
}
#[test]
fn test_words_with_oxford_commas () {
assert_eq!("", words_with_oxford_commas(&[]));
assert_eq!("a", words_with_oxford_commas(&["a"]));
assert_eq!("a and b", words_with_oxford_commas(&["a", "b"]));
assert_eq!("a, b, and c", words_with_oxford_commas(&["a", "b", "c"]));
}
#[test]
fn test_word_wrap () {
assert_eq!(vec!["abc"],
word_wrap("abc", 30));
assert_eq!(vec!["abc def ghi"],
word_wrap("abc def ghi", 30));
assert_eq!(vec!["abc def", "ghi"],
word_wrap("abc def ghi", 8));
assert_eq!(vec!["abc", "def", "ghi"],
word_wrap("abc def ghi", 4));
}
}