string_stupidify/
decorator.rs1#[derive(Debug)]
2pub enum DecorationError {
3    Unknown(Option<String>),
4    StringEmpty,
5}
6
7pub trait StringDecorator {
8    fn decorate(&self, text: &String) -> Result<String, DecorationError>;
9}
10
11pub trait ForcedStringDecorator {
12    fn force_decorate(&self, text: &String) -> String;
13}
14
15impl<T> ForcedStringDecorator for T where T: StringDecorator {
16    fn force_decorate(&self, text: &String) -> String {
17        match self.decorate(text) {
18            Ok(s) => s,
19            Err(e) => panic!("Error decorating text: {:?}", e),
20        }
21    }
22}
23
24pub trait Decoratable {
25    fn decorate(&self, decorators: &Vec<Box<dyn StringDecorator>>) -> Result<String, DecorationError>;
26}
27
28impl<T> Decoratable for T where T: ToString {
29    fn decorate(&self, decorators: &Vec<Box<dyn StringDecorator>>) -> Result<String, DecorationError> {
30        let mut s = self.to_string();
31        for decorator in decorators {
32            match decorator.decorate(&s) {
33                Ok(decorated) => s = decorated,
34                error => return error,
35            }
36        }
37        Ok(s)
38    }
39}
40
41#[cfg(test)]
42mod decoratable_tests {
43    use crate::{Decoratable, StringDecorator};
44    use crate::decorators::{Alternate, VaporWave};
45
46    #[test]
47    fn test_decorate() {
48        let text = "Hello, World";
49        let decorators: Vec<Box<dyn StringDecorator>> = vec![
50            Box::new(VaporWave),
51            Box::new(Alternate),
52        ];
53        assert_eq!("H e L l O ,   w O r L d".to_string(), text.decorate(&decorators).unwrap());
54    }
55}