use std::fmt::Display;
pub trait NaturalJoin {
fn natural_join(self) -> String;
}
impl<I> NaturalJoin for I
where
I: Iterator,
I::Item: Display,
{
fn natural_join(self) -> String {
let mut iter = self.peekable();
let mut output = String::new();
match iter.next() {
None => return output,
Some(fst) => {
if iter.peek().is_none() {
return fst.to_string();
}
output.push_str(&fst.to_string())
},
}
while let Some(curr) = iter.next() {
if iter.peek().is_none() {
output.push_str(" and ");
} else {
output.push_str(", ");
}
output.push_str(&curr.to_string());
}
output
}
}
#[cfg(test)]
mod natural_join_tests {
use crate::NaturalJoin;
#[test]
fn natural_join_nothing() {
let v: Vec<String> = vec![];
let s = v.iter().natural_join();
assert_eq!("", s);
}
#[test]
fn natural_join_single() {
let a = ["A"];
let s = a.iter().natural_join();
assert_eq!("A", s);
}
#[test]
fn natural_join_two() {
let v = ["A", "B"];
let s = v.iter().natural_join();
assert_eq!("A and B", s);
}
#[test]
fn natural_join_three() {
let v = ["A", "B", "C"];
let s = v.iter().natural_join();
assert_eq!("A, B and C", s);
}
}