logform/formats/
format.rs

1pub trait Format {
2    type Input;
3
4    fn transform(&self, input: Self::Input) -> Option<Self::Input>;
5
6    fn chain<F>(self, next: F) -> ChainedFormat<Self, F>
7    where
8        Self: Sized,
9        F: Format<Input = Self::Input>,
10    {
11        ChainedFormat { first: self, next }
12    }
13}
14
15pub struct ChainedFormat<F1, F2> {
16    first: F1,
17    next: F2,
18}
19
20impl<T, F1, F2> Format for ChainedFormat<F1, F2>
21where
22    F1: Format<Input = T>,
23    F2: Format<Input = T>,
24{
25    type Input = T;
26
27    fn transform(&self, input: T) -> Option<T> {
28        self.first
29            .transform(input)
30            .and_then(|res| self.next.transform(res))
31    }
32}
33
34// Example format implementations
35struct UpperCase;
36impl Format for UpperCase {
37    type Input = String;
38
39    fn transform(&self, input: String) -> Option<Self::Input> {
40        Some(input.to_uppercase())
41    }
42}
43
44struct NonEmpty;
45
46impl Format for NonEmpty {
47    type Input = String;
48
49    fn transform(&self, input: String) -> Option<Self::Input> {
50        if input.is_empty() {
51            None
52        } else {
53            Some(input)
54        }
55    }
56}
57
58struct ReverseFormat;
59impl Format for ReverseFormat {
60    type Input = String;
61
62    fn transform(&self, input: String) -> Option<Self::Input> {
63        Some(input.chars().rev().collect())
64    }
65}
66
67#[derive(Clone)]
68struct AddSuffix(String);
69impl Format for AddSuffix {
70    type Input = String;
71
72    fn transform(&self, input: String) -> Option<Self::Input> {
73        Some(format!("{}{}", input, self.0))
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_proposed_format() {
83        let upper = UpperCase;
84        let reverse = ReverseFormat;
85        let suffix = AddSuffix("-end".to_string());
86
87        let format = upper.chain(reverse).chain(suffix);
88
89        let result = format.transform("hello".to_string());
90
91        assert_eq!(result, Some("OLLEH-end".to_string()));
92    }
93}