1pub mod ranking;
2pub mod suggestions;
3
4pub use ranking::SuggestionRanker;
5pub use suggestions::CompletionSuggestion;
6
7use crate::code::code_completion::context::CompletionContext;
8use crate::code::code_completion::learning::CompletionLearningData;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11use std::sync::Arc;
12use tokio::sync::RwLock;
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
16pub enum CompletionKind {
17 Function,
18 Method,
19 Variable,
20 Class,
21 Struct,
22 Enum,
23 Trait,
24 Module,
25 Keyword,
26 Snippet,
27 Import,
28 Type,
29}
30
31pub struct CompletionEngine {
33 suggestion_cache: Arc<RwLock<HashMap<String, Vec<CompletionSuggestion>>>>,
34 learning_data: Arc<RwLock<CompletionLearningData>>,
35 performance_stats: Arc<RwLock<CompletionStats>>,
36}
37
38#[derive(Debug, Clone, Default)]
40pub struct CompletionStats {
41 pub total_requests: usize,
42 pub cache_hits: usize,
43 pub average_response_time_ms: f64,
44 pub acceptance_rate: f64,
45}
46
47impl CompletionEngine {
48 pub fn new() -> Self {
49 Self {
50 suggestion_cache: Arc::new(RwLock::new(HashMap::new())),
51 learning_data: Arc::new(RwLock::new(CompletionLearningData::default())),
52 performance_stats: Arc::new(RwLock::new(CompletionStats::default())),
53 }
54 }
55
56 pub async fn complete(&self, context: &CompletionContext) -> Vec<CompletionSuggestion> {
58 let cache_key = format!("{}:{}:{}", context.language, context.line, context.column);
60 {
61 let cache = self.suggestion_cache.read().await;
62 if let Some(cached) = cache.get(&cache_key) {
63 return cached.clone();
64 }
65 }
66
67 let mut suggestions = Vec::new();
69
70 let keywords = self.get_language_keywords(&context.language);
72 for keyword in keywords {
73 if keyword.starts_with(&context.prefix) {
74 suggestions.push(CompletionSuggestion {
75 text: keyword.to_string(),
76 kind: CompletionKind::Keyword,
77 confidence: 0.8,
78 context: context.clone(),
79 metadata: HashMap::new(),
80 acceptance_rate: 0.0,
81 learning_data: CompletionLearningData::default(),
82 accepted_count: 0,
83 rejected_count: 0,
84 });
85 }
86 }
87
88 let snippets = self.get_language_snippets(&context.language);
90 for snippet in snippets {
91 if snippet.label.starts_with(&context.prefix) {
92 suggestions.push(CompletionSuggestion {
93 text: snippet.template,
94 kind: CompletionKind::Snippet,
95 confidence: 0.7,
96 context: context.clone(),
97 metadata: HashMap::from([
98 ("label".to_string(), snippet.label),
99 ("description".to_string(), snippet.description),
100 ]),
101 acceptance_rate: 0.0,
102 learning_data: CompletionLearningData::default(),
103 accepted_count: 0,
104 rejected_count: 0,
105 });
106 }
107 }
108
109 {
111 let mut cache = self.suggestion_cache.write().await;
112 cache.insert(cache_key, suggestions.clone());
113 }
114
115 suggestions
116 }
117
118 pub async fn record_feedback(&self, suggestion_id: &str, accepted: bool) {
120 let mut learning_data = self.learning_data.write().await;
121
122 let current_rate = learning_data
124 .pattern_acceptance
125 .get(suggestion_id)
126 .copied()
127 .unwrap_or(0.0);
128 let new_rate = if accepted {
129 (current_rate + 1.0) / 2.0
130 } else {
131 current_rate * 0.9
132 };
133 learning_data
134 .pattern_acceptance
135 .insert(suggestion_id.to_string(), new_rate);
136
137 let mut stats = self.performance_stats.write().await;
139 stats.total_requests += 1;
140 if accepted {
141 stats.acceptance_rate = (stats.acceptance_rate * (stats.total_requests - 1) as f64
142 + 1.0)
143 / stats.total_requests as f64;
144 }
145 }
146
147 fn get_language_keywords(&self, language: &str) -> Vec<&'static str> {
149 match language {
150 "rust" => vec![
151 "fn", "let", "mut", "const", "static", "struct", "enum", "impl", "trait", "mod",
152 "use", "pub", "crate", "super", "self", "Self", "async", "await", "move", "if",
153 "else", "match", "loop", "while", "for", "in", "break", "continue", "return", "as",
154 "dyn", "where", "unsafe",
155 ],
156 "python" => vec![
157 "def", "class", "if", "elif", "else", "for", "while", "try", "except", "finally",
158 "with", "as", "import", "from", "return", "yield", "lambda", "and", "or", "not",
159 "in", "is", "None", "True", "False", "self", "super",
160 ],
161 "javascript" => vec![
162 "function",
163 "const",
164 "let",
165 "var",
166 "if",
167 "else",
168 "for",
169 "while",
170 "try",
171 "catch",
172 "finally",
173 "return",
174 "async",
175 "await",
176 "class",
177 "extends",
178 "import",
179 "export",
180 "from",
181 "as",
182 "this",
183 "super",
184 "new",
185 "typeof",
186 "instanceof",
187 ],
188 _ => vec![],
189 }
190 }
191
192 fn get_language_snippets(&self, language: &str) -> Vec<CodeSnippet> {
194 match language {
195 "rust" => vec![
196 CodeSnippet {
197 label: "fn".to_string(),
198 template: "fn ${1:name}(${2:params}) -> ${3:ReturnType} {\n\t${0:// body}\n}".to_string(),
199 description: "Function declaration".to_string(),
200 },
201 CodeSnippet {
202 label: "impl".to_string(),
203 template: "impl ${1:Trait} for ${2:Type} {\n\t${0:// implementation}\n}".to_string(),
204 description: "Implementation block".to_string(),
205 },
206 ],
207 "python" => vec![
208 CodeSnippet {
209 label: "def".to_string(),
210 template: "def ${1:name}(${2:params}):\n\t${0:# body}".to_string(),
211 description: "Function definition".to_string(),
212 },
213 CodeSnippet {
214 label: "class".to_string(),
215 template: "class ${1:Name}:\n\tdef __init__(self${2:params}):\n\t\t${0:# initialization}".to_string(),
216 description: "Class definition".to_string(),
217 },
218 ],
219 "javascript" => vec![
220 CodeSnippet {
221 label: "func".to_string(),
222 template: "function ${1:name}(${2:params}) {\n\t${0:// body}\n}".to_string(),
223 description: "Function declaration".to_string(),
224 },
225 CodeSnippet {
226 label: "class".to_string(),
227 template: "class ${1:Name} {\n\tconstructor(${2:params}) {\n\t\t${0:// initialization}\n\t}\n}".to_string(),
228 description: "Class declaration".to_string(),
229 },
230 ],
231 _ => vec![],
232 }
233 }
234}
235
236impl Default for CompletionEngine {
237 fn default() -> Self {
238 Self::new()
239 }
240}
241
242#[derive(Debug, Clone)]
244pub struct CodeSnippet {
245 pub label: String,
246 pub template: String,
247 pub description: String,
248}