claude_agent/common/
index.rs1use async_trait::async_trait;
7
8use super::{ContentSource, Named, SourceType};
9
10#[async_trait]
40pub trait Index: Named + Clone + Send + Sync + 'static {
41 fn source(&self) -> &ContentSource;
43
44 fn source_type(&self) -> SourceType;
46
47 fn priority(&self) -> i32 {
52 match self.source_type() {
53 SourceType::Project => 20,
54 SourceType::User => 10,
55 SourceType::Builtin => 0,
56 SourceType::Managed => 5,
57 }
58 }
59
60 fn to_summary_line(&self) -> String;
64
65 async fn load_content(&self) -> crate::Result<String> {
69 self.source().load().await
70 }
71
72 fn description(&self) -> &str {
74 ""
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use async_trait::async_trait;
81
82 use super::*;
83 use crate::common::Named;
84
85 #[derive(Clone, Debug)]
86 struct TestIndex {
87 name: String,
88 desc: String,
89 source: ContentSource,
90 source_type: SourceType,
91 }
92
93 impl Named for TestIndex {
94 fn name(&self) -> &str {
95 &self.name
96 }
97 }
98
99 #[async_trait]
100 impl Index for TestIndex {
101 fn source(&self) -> &ContentSource {
102 &self.source
103 }
104
105 fn source_type(&self) -> SourceType {
106 self.source_type
107 }
108
109 fn to_summary_line(&self) -> String {
110 format!("- {}: {}", self.name, self.desc)
111 }
112
113 fn description(&self) -> &str {
114 &self.desc
115 }
116 }
117
118 #[test]
119 fn test_priority_ordering() {
120 let builtin = TestIndex {
121 name: "test".into(),
122 desc: "desc".into(),
123 source: ContentSource::in_memory(""),
124 source_type: SourceType::Builtin,
125 };
126
127 let user = TestIndex {
128 name: "test".into(),
129 desc: "desc".into(),
130 source: ContentSource::in_memory(""),
131 source_type: SourceType::User,
132 };
133
134 let project = TestIndex {
135 name: "test".into(),
136 desc: "desc".into(),
137 source: ContentSource::in_memory(""),
138 source_type: SourceType::Project,
139 };
140
141 assert!(project.priority() > user.priority());
142 assert!(user.priority() > builtin.priority());
143 }
144
145 #[tokio::test]
146 async fn test_load_content() {
147 let index = TestIndex {
148 name: "test".into(),
149 desc: "desc".into(),
150 source: ContentSource::in_memory("full content here"),
151 source_type: SourceType::User,
152 };
153
154 let content = index.load_content().await.unwrap();
155 assert_eq!(content, "full content here");
156 }
157
158 #[test]
159 fn test_summary_line() {
160 let index = TestIndex {
161 name: "commit".into(),
162 desc: "Create git commits".into(),
163 source: ContentSource::in_memory(""),
164 source_type: SourceType::User,
165 };
166
167 assert_eq!(index.to_summary_line(), "- commit: Create git commits");
168 }
169}