ai_descriptor_trait/
lib.rs1use std::borrow::Cow;
2
3pub trait ItemFeature {
4 fn text(&self) -> Cow<'_,str>;
5}
6
7pub trait ItemWithFeatures {
8 fn header(&self) -> Cow<'_,str>;
9 fn features(&self) -> Vec<Cow<'_, str>>;
10}
11
12pub trait AIDescriptor {
13 fn ai(&self) -> Cow<'_,str>;
14 fn ai_alt(&self) -> Cow<'_,str> {
15 unimplemented!("can implement this function for ai_alt() function")
16 }
17}
18
19impl<T: ItemWithFeatures> AIDescriptor for T {
20
21 fn ai(&self) -> Cow<'_,str> {
22 let mut lines: Vec<String> = vec![];
23 lines.push(self.header().into());
24 lines.push("It has the following features:".into());
25
26 for feature in self.features() {
27 lines.push(format!("- {}", feature));
28 }
29 Cow::Owned(lines.join("\n"))
30 }
31
32 fn ai_alt(&self) -> Cow<'_,str> {
33 let mut lines: Vec<String> = vec![];
34
35 for feature in self.features() {
36 lines.push(feature.into());
37 }
38 Cow::Owned(lines.join(" "))
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 struct TestItem {
47 header: String,
48 features: Vec<Cow<'static, str>>,
49 }
50
51 impl ItemWithFeatures for TestItem {
52 fn header(&self) -> Cow<'_, str> {
53 Cow::Borrowed(&self.header)
54 }
55
56 fn features(&self) -> Vec<Cow<'_, str>> {
57 self.features.clone()
58 }
59 }
60
61 #[test]
62 fn test_ai_descriptor() {
63 let item = TestItem {
64 header: "An Item.".to_string(),
65 features: vec![
66 Cow::Borrowed("Feature 1"),
67 Cow::Borrowed("Feature 2"),
68 Cow::Borrowed("Feature 3"),
69 ],
70 };
71
72 let expected_output = "\
73An Item.
74It has the following features:
75- Feature 1
76- Feature 2
77- Feature 3";
78
79 assert_eq!(item.ai(), expected_output);
80 }
81}