use std::string::ToString;
pub trait MultiPrint : ToString {
fn times(&self, n: usize, sep: char) -> String {
let mut str = String::new();
for i in 0..n {
if i < n && i > 0 {
str.push(sep);
}
str.push_str(&self.to_string());
}
str
}
}
pub trait Decorate : ToString {
fn underline(&self, underline_character: char) -> String;
fn overline(&self, overline_character: char) -> String;
fn outline(&self, overline_character: char, underline_character: char) -> String;
fn border(&self, line_character: char, side_character: char) -> String;
}
impl MultiPrint for String {}
impl Decorate for String {
fn underline(&self, underline_character: char) -> String {
format!("{}\n{}", self.to_string(), std::iter::repeat(underline_character).take(self.len()).collect::<String>())
}
fn overline(&self, overline_character: char) -> String {
format!("{}\n{}", std::iter::repeat(overline_character).take(self.len()).collect::<String>(), self.to_string())
}
fn outline(&self, overline_character: char, underline_character: char) -> String {
format!("{}\n{}\n{}",
std::iter::repeat(overline_character).take(self.len()).collect::<String>(),
self.to_string(),
std::iter::repeat(underline_character).take(self.len()).collect::<String>()
)
}
fn border(&self, line_character: char, side_character: char) -> String {
format!("{}\n{} {} {}\n{}",
std::iter::repeat(line_character).take(self.len()+4).collect::<String>(),
side_character,
self.to_string(),
side_character,
std::iter::repeat(line_character).take(self.len()+4).collect::<String>()
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hello_twice() {
let s = String::from("Hello");
assert_eq!(s.times(2, ' '), "Hello Hello");
}
#[test]
fn do_it_5_times() {
let s = String::from("Peter");
assert_eq!(s.times(5, '-'), "Peter-Peter-Peter-Peter-Peter");
}
#[test]
fn underline_test() {
let s = String::from("This is a header");
assert_eq!(s.underline('-'), "This is a header\n----------------");
}
#[test]
fn overline_test() {
let s = String::from("This is a header");
assert_eq!(s.overline('-'), "----------------\nThis is a header");
}
#[test]
fn outline() {
let s = String::from("This is a header");
assert_eq!(s.outline('-', '='), "----------------\nThis is a header\n================");
}
#[test]
fn border() {
let s = String::from("Bordered");
assert_eq!(s.border('-', '|'), "------------\n| Bordered |\n------------");
}
}