named_item/
ai_descriptor.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
crate::ix!();

pub trait ItemFeature {
    fn text(&self) -> Cow<'_,str>;
}

pub trait ItemWithFeatures {
    fn header(&self) -> Cow<'_,str>;
    fn features(&self) -> Vec<Cow<'_, str>>;
}

pub trait AIDescriptor {
    fn ai(&self) -> Cow<'_,str>;
}

impl<T: ItemWithFeatures> AIDescriptor for T {

    fn ai(&self) -> Cow<'_,str> {
        let mut lines: Vec<String> = vec![];
        lines.push(self.header().into());
        lines.push("It has the following features:".into());

        for feature in self.features() {
            lines.push(format!("- {}", feature));
        }
        Cow::Owned(lines.join("\n"))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    struct TestItem {
        header: String,
        features: Vec<Cow<'static, str>>,
    }

    impl ItemWithFeatures for TestItem {
        fn header(&self) -> Cow<'_, str> {
            Cow::Borrowed(&self.header)
        }

        fn features(&self) -> Vec<Cow<'_, str>> {
            &self.features
        }
    }

    #[test]
    fn test_ai_descriptor() {
        let item = TestItem {
            header: "An Item.".to_string(),
            features: vec![
                Cow::Borrowed("Feature 1"),
                Cow::Borrowed("Feature 2"),
                Cow::Borrowed("Feature 3"),
            ],
        };

        let expected_output = "\
An Item.
It has the following features:
- Feature 1
- Feature 2
- Feature 3";

        assert_eq!(item.ai(), expected_output);
    }
}