160 lines
4.6 KiB
Rust
160 lines
4.6 KiB
Rust
/*!
|
|
* Provides traits and helpers for generating and manipulating written lanuage constructs
|
|
*/
|
|
|
|
/// A type that can be compiled into a sentence.
|
|
pub trait ToSentence {
|
|
/// Sentencifies self. The result should be suitable to be placed within a sentence.
|
|
fn to_sentence(&self) -> String;
|
|
|
|
/// Sentencifies self, upper-casing the first letter and adding a period to the end. Using this is discouraged due to its lack of flexibility (i.e. needing alternate punctuation or a lowercase first letter).
|
|
fn to_sentence_finalize(&self) -> String {
|
|
let s = self.to_sentence();
|
|
let mut c = s.chars();
|
|
match s.len() {
|
|
0 => format!(""),
|
|
1 => format!("{}.", s.to_uppercase()),
|
|
_ => format!("{}{}.", c.nth(0).unwrap().to_uppercase(), c.as_str()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, T> ToSentence for T where T: AsRef<[&'a str]> {
|
|
fn to_sentence(&self) -> String {
|
|
let s = self.as_ref();
|
|
let len = s.len();
|
|
let mut str = String::new();
|
|
for (i, seg) in s.iter().map(|s| s.as_ref()).enumerate() {
|
|
if i == 0 {
|
|
str.push_str(seg);
|
|
} else if i == len-1 {
|
|
if len == 2 {
|
|
str.push_str(&format!(" and {}", seg));
|
|
} else {
|
|
str.push_str(&format!(", and {}", seg));
|
|
}
|
|
} else {
|
|
str.push_str(&format!(", {}", seg));
|
|
}
|
|
}
|
|
str
|
|
}
|
|
}
|
|
|
|
// impl<T> ToSentence for T where T: AsRef<[String]> {
|
|
// fn to_sentence(&self) -> String {
|
|
// let s = self.as_ref();
|
|
// let len = s.len();
|
|
// let mut str = String::new();
|
|
// for (i, seg) in s.iter().map(|s| s.as_ref()).enumerate() {
|
|
// if i == 0 {
|
|
// str.push_str(seg);
|
|
// } else if i == len {
|
|
// if len == 2 {
|
|
// str.push_str(&format!(" and {}", seg));
|
|
// } else {
|
|
// str.push_str(&format!(", and {}", seg));
|
|
// }
|
|
// } else {
|
|
// str.push_str(&format!(", {}", seg));
|
|
// }
|
|
// }
|
|
// str
|
|
// }
|
|
// }
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::ToSentence;
|
|
|
|
const STRING_SLICE_A: &'static [&'static str] = &[
|
|
"a",
|
|
];
|
|
|
|
const STRING_SLICE_B: &'static [&'static str] = &[
|
|
"a",
|
|
"b",
|
|
];
|
|
|
|
const STRING_SLICE_C: &'static [&'static str] = &[
|
|
"a",
|
|
"b",
|
|
"c",
|
|
"d",
|
|
"e",
|
|
"f",
|
|
"g",
|
|
];
|
|
|
|
#[test]
|
|
fn str_slice_to_sentence() {
|
|
assert_eq!(STRING_SLICE_A.to_sentence(), "a");
|
|
assert_eq!(STRING_SLICE_B.to_sentence(), "a and b");
|
|
assert_eq!(STRING_SLICE_C.to_sentence(), "a, b, c, d, e, f, and g");
|
|
}
|
|
|
|
#[test]
|
|
fn str_slice_to_sentence_finalize() {
|
|
assert_eq!(STRING_SLICE_A.to_sentence_finalize(), "A.");
|
|
assert_eq!(STRING_SLICE_B.to_sentence_finalize(), "A and b.");
|
|
assert_eq!(STRING_SLICE_C.to_sentence_finalize(), "A, b, c, d, e, f, and g.");
|
|
}
|
|
|
|
#[test]
|
|
fn string_vec_to_sentence() {
|
|
let vec: Vec<String> = vec!{
|
|
"a".to_owned(),
|
|
};
|
|
|
|
assert_eq!(vec.iter().map(|e| e.as_ref()).collect::<Vec<&str>>().to_sentence(), "a");
|
|
|
|
let vec: Vec<String> = vec!{
|
|
"a".to_owned(),
|
|
"b".to_owned(),
|
|
};
|
|
|
|
assert_eq!(vec.iter().map(|e| e.as_ref()).collect::<Vec<&str>>().to_sentence(), "a and b");
|
|
|
|
let vec: Vec<String> = vec!{
|
|
"a".to_owned(),
|
|
"b".to_owned(),
|
|
"c".to_owned(),
|
|
"d".to_owned(),
|
|
"e".to_owned(),
|
|
"f".to_owned(),
|
|
"g".to_owned(),
|
|
};
|
|
|
|
assert_eq!(vec.iter().map(|e| e.as_ref()).collect::<Vec<&str>>().to_sentence(), "a, b, c, d, e, f, and g");
|
|
}
|
|
|
|
#[test]
|
|
fn string_vec_to_sentence_finalize() {
|
|
let vec: Vec<String> = vec!{
|
|
"a".to_owned(),
|
|
};
|
|
|
|
assert_eq!(vec.iter().map(|e| e.as_ref()).collect::<Vec<&str>>().to_sentence_finalize(), "A.");
|
|
|
|
let vec: Vec<String> = vec!{
|
|
"a".to_owned(),
|
|
"b".to_owned(),
|
|
};
|
|
|
|
assert_eq!(vec.iter().map(|e| e.as_ref()).collect::<Vec<&str>>().to_sentence_finalize(), "A and b.");
|
|
|
|
let vec: Vec<String> = vec!{
|
|
"a".to_owned(),
|
|
"b".to_owned(),
|
|
"c".to_owned(),
|
|
"d".to_owned(),
|
|
"e".to_owned(),
|
|
"f".to_owned(),
|
|
"g".to_owned(),
|
|
};
|
|
|
|
assert_eq!(vec.iter().map(|e| e.as_ref()).collect::<Vec<&str>>().to_sentence_finalize(), "A, b, c, d, e, f, and g.");
|
|
}
|
|
}
|
|
|