1use crate::api_generator_config::{GeneratorConfig, PlaygroundConfig};
8use crate::error::{Result, SklearsError};
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11use std::time::Duration;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct ApiReference {
20 pub crate_name: String,
22 pub version: String,
24 pub traits: Vec<TraitInfo>,
26 pub types: Vec<TypeInfo>,
28 pub examples: Vec<CodeExample>,
30 pub cross_references: HashMap<String, Vec<String>>,
32 pub metadata: ApiMetadata,
34}
35
36impl ApiReference {
37 pub fn to_json(&self) -> Result<String> {
39 serde_json::to_string_pretty(self)
40 .map_err(|e| SklearsError::InvalidInput(format!("JSON serialization failed: {}", e)))
41 }
42
43 pub fn to_html(&self) -> Result<String> {
45 let mut html = String::new();
46 html.push_str(&format!(
47 "<html><head><title>API Reference - {}</title></head><body>",
48 self.crate_name
49 ));
50 html.push_str(&format!("<h1>API Reference for {}</h1>", self.crate_name));
51
52 if !self.traits.is_empty() {
54 html.push_str("<h2>Traits</h2>");
55 for trait_info in &self.traits {
56 html.push_str(&format!("<h3>{}</h3>", trait_info.name));
57 html.push_str(&format!("<p>{}</p>", trait_info.description));
58
59 if !trait_info.methods.is_empty() {
60 html.push_str("<h4>Methods</h4><ul>");
61 for method in &trait_info.methods {
62 html.push_str(&format!(
63 "<li><code>{}</code> - {}</li>",
64 method.signature, method.description
65 ));
66 }
67 html.push_str("</ul>");
68 }
69 }
70 }
71
72 if !self.types.is_empty() {
74 html.push_str("<h2>Types</h2>");
75 for type_info in &self.types {
76 html.push_str(&format!("<h3>{}</h3>", type_info.name));
77 html.push_str(&format!("<p>{}</p>", type_info.description));
78 }
79 }
80
81 if !self.examples.is_empty() {
83 html.push_str("<h2>Examples</h2>");
84 for example in &self.examples {
85 html.push_str(&format!("<h3>{}</h3>", example.title));
86 html.push_str(&format!("<p>{}</p>", example.description));
87 html.push_str(&format!(
88 "<pre><code class=\"{}\">{}</code></pre>",
89 example.language, example.code
90 ));
91 }
92 }
93
94 html.push_str("</body></html>");
95 Ok(html)
96 }
97
98 pub fn to_markdown(&self) -> Result<String> {
100 let mut md = String::new();
101 md.push_str(&format!("# API Reference - {}\n\n", self.crate_name));
102 md.push_str(&format!("Version: {}\n\n", self.version));
103
104 if !self.traits.is_empty() {
106 md.push_str("## Traits\n\n");
107 for trait_info in &self.traits {
108 md.push_str(&format!("### {}\n\n", trait_info.name));
109 md.push_str(&format!("{}\n\n", trait_info.description));
110
111 if !trait_info.methods.is_empty() {
112 md.push_str("#### Methods\n\n");
113 for method in &trait_info.methods {
114 md.push_str(&format!(
115 "- `{}` - {}\n",
116 method.signature, method.description
117 ));
118 }
119 md.push('\n');
120 }
121 }
122 }
123
124 if !self.types.is_empty() {
126 md.push_str("## Types\n\n");
127 for type_info in &self.types {
128 md.push_str(&format!("### {}\n\n", type_info.name));
129 md.push_str(&format!("{}\n\n", type_info.description));
130 }
131 }
132
133 if !self.examples.is_empty() {
135 md.push_str("## Examples\n\n");
136 for example in &self.examples {
137 md.push_str(&format!("### {}\n\n", example.title));
138 md.push_str(&format!("{}\n\n", example.description));
139 md.push_str(&format!(
140 "```{}\n{}\n```\n\n",
141 example.language, example.code
142 ));
143 }
144 }
145
146 Ok(md)
147 }
148
149 pub fn to_interactive(&self) -> Result<String> {
151 let mut html = String::new();
152 html.push_str("<!DOCTYPE html><html><head>");
153 html.push_str("<title>Interactive API Reference</title>");
154 html.push_str(
155 "<script src=\"https://unpkg.com/@webassembly/wasi-sdk@0.11.0/bin/wasm-ld\"></script>",
156 );
157 html.push_str("</head><body>");
158 html.push_str(&format!(
159 "<h1>Interactive Reference - {}</h1>",
160 self.crate_name
161 ));
162 html.push_str("<div id=\"playground\">");
163 html.push_str("<textarea id=\"code-editor\" rows=\"20\" cols=\"80\">");
164
165 if let Some(example) = self.examples.first() {
167 html.push_str(&example.code);
168 } else {
169 html.push_str(
170 "// Write your code here\nfn main() {\n println!(\"Hello, sklears!\");\n}",
171 );
172 }
173
174 html.push_str("</textarea>");
175 html.push_str("<br><button onclick=\"runCode()\">Run Code</button>");
176 html.push_str("<div id=\"output\"></div>");
177 html.push_str("</div>");
178 html.push_str("<script>");
179 html.push_str("function runCode() {");
180 html.push_str(" const code = document.getElementById('code-editor').value;");
181 html.push_str(
182 " document.getElementById('output').innerHTML = 'Code execution would happen here';",
183 );
184 html.push('}');
185 html.push_str("</script>");
186 html.push_str("</body></html>");
187
188 Ok(html)
189 }
190}
191
192#[derive(Debug, Clone)]
194#[allow(dead_code)]
195pub struct CrateInfo {
196 pub name: String,
197 pub version: String,
198 pub description: String,
199 pub modules: Vec<String>,
200 pub dependencies: Vec<String>,
201}
202
203#[derive(Debug, Clone, Serialize, Deserialize)]
205pub struct ApiMetadata {
206 pub generation_time: String,
208 pub generator_version: String,
210 pub crate_version: String,
212 pub rust_version: String,
214 pub config: GeneratorConfig,
216}
217
218impl Default for ApiMetadata {
219 fn default() -> Self {
220 Self {
221 generation_time: chrono::Utc::now().to_string(),
222 generator_version: env!("CARGO_PKG_VERSION").to_string(),
223 crate_version: "unknown".to_string(),
224 rust_version: env!("CARGO_PKG_RUST_VERSION").to_string(),
225 config: GeneratorConfig::default(),
226 }
227 }
228}
229
230#[derive(Debug, Clone, Serialize, Deserialize, Default)]
236pub struct TraitInfo {
237 pub name: String,
239 pub description: String,
241 pub path: String,
243 pub generics: Vec<String>,
245 pub associated_types: Vec<AssociatedType>,
247 pub methods: Vec<MethodInfo>,
249 pub supertraits: Vec<String>,
251 pub implementations: Vec<String>,
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize, Default)]
257pub struct AssociatedType {
258 pub name: String,
260 pub description: String,
262 pub bounds: Vec<String>,
264}
265
266#[derive(Debug, Clone, Serialize, Deserialize, Default)]
268pub struct MethodInfo {
269 pub name: String,
271 pub signature: String,
273 pub description: String,
275 pub parameters: Vec<ParameterInfo>,
277 pub return_type: String,
279 pub required: bool,
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize, Default)]
285pub struct ParameterInfo {
286 pub name: String,
288 pub param_type: String,
290 pub description: String,
292 pub optional: bool,
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize)]
302pub struct TypeInfo {
303 pub name: String,
305 pub description: String,
307 pub path: String,
309 pub kind: TypeKind,
311 pub generics: Vec<String>,
313 pub fields: Vec<FieldInfo>,
315 pub trait_impls: Vec<String>,
317}
318
319#[derive(Debug, Clone, Serialize, Deserialize)]
321pub enum TypeKind {
322 Struct,
323 Enum,
324 Union,
325 TypeAlias,
326 Trait,
327}
328
329#[derive(Debug, Clone, Serialize, Deserialize)]
331pub struct FieldInfo {
332 pub name: String,
334 pub field_type: String,
336 pub description: String,
338 pub visibility: Visibility,
340}
341
342#[derive(Debug, Clone, Serialize, Deserialize)]
344pub enum Visibility {
345 Public,
346 Private,
347 Restricted(String),
348}
349
350#[derive(Debug, Clone, Serialize, Deserialize)]
356pub struct CodeExample {
357 pub title: String,
359 pub description: String,
361 pub code: String,
363 pub language: String,
365 pub runnable: bool,
367 pub expected_output: Option<String>,
369}
370
371#[derive(Debug, Clone, Serialize, Deserialize)]
373pub struct ExecutionResult {
374 pub stdout: String,
376 pub stderr: String,
378 pub exit_code: i32,
380 pub execution_time: Duration,
382 pub memory_used: usize,
384 pub output: String,
386}
387
388#[derive(Debug, Clone, Serialize, Deserialize)]
394pub struct InteractiveDocumentation {
395 pub api_reference: ApiReference,
397 pub live_examples: Vec<LiveCodeExample>,
399 pub searchable_index: SearchIndex,
401 pub interactive_tutorials: Vec<InteractiveTutorial>,
403 pub visualizations: Vec<ApiVisualization>,
405 pub playground_config: PlaygroundConfig,
407}
408
409#[derive(Debug, Clone, Serialize, Deserialize)]
411pub struct LiveCodeExample {
412 pub original_example: CodeExample,
414 pub execution_result: ExecutionResult,
416 pub interactive_elements: Vec<InteractiveElement>,
418 pub visualization: ExampleVisualization,
420 pub editable: bool,
422 pub real_time_feedback: bool,
424}
425
426#[derive(Debug, Clone, Serialize, Deserialize)]
428pub struct InteractiveElement {
429 pub element_type: InteractiveElementType,
431 pub id: String,
433 pub label: String,
435 pub action: String,
437 pub target: String,
439}
440
441#[derive(Debug, Clone, Serialize, Deserialize)]
443pub enum InteractiveElementType {
444 Button,
445 Slider,
446 Toggle,
447 Input,
448 Dropdown,
449}
450
451#[derive(Debug, Clone, Serialize, Deserialize)]
453pub struct ExampleVisualization {
454 pub visualization_type: VisualizationType,
456 pub data: String,
458 pub interactive: bool,
460 pub real_time_updates: bool,
462 pub config: VisualizationConfig,
464}
465
466#[derive(Debug, Clone, Serialize, Deserialize)]
468pub enum VisualizationType {
469 FlowChart,
470 Graph,
471 Timeline,
472 Tree,
473 Network,
474 Chart,
475}
476
477#[derive(Debug, Clone, Serialize, Deserialize)]
479pub struct VisualizationConfig {
480 pub width: u32,
482 pub height: u32,
484 pub theme: String,
486 pub animation_enabled: bool,
488}
489
490#[derive(Debug, Clone, Serialize, Deserialize)]
492pub struct InteractiveTutorial {
493 pub title: String,
495 pub description: String,
497 pub steps: Vec<TutorialStep>,
499 pub difficulty: TutorialDifficulty,
501 pub estimated_time: Duration,
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize)]
507pub struct TutorialStep {
508 pub title: String,
510 pub content: String,
512 pub code_example: Option<CodeExample>,
514 pub interactive_elements: Vec<InteractiveElement>,
516 pub expected_outcome: String,
518}
519
520#[derive(Debug, Clone, Serialize, Deserialize)]
522pub enum TutorialDifficulty {
523 Beginner,
524 Intermediate,
525 Advanced,
526 Expert,
527}
528
529#[derive(Debug, Clone, Serialize, Deserialize)]
531pub struct ApiVisualization {
532 pub title: String,
534 pub visualization_type: VisualizationType,
536 pub data: ApiVisualizationData,
538 pub config: VisualizationConfig,
540}
541
542#[derive(Debug, Clone, Serialize, Deserialize)]
544pub struct ApiVisualizationData {
545 pub nodes: Vec<VisualizationNode>,
547 pub edges: Vec<VisualizationEdge>,
549 pub metadata: HashMap<String, String>,
551}
552
553#[derive(Debug, Clone, Serialize, Deserialize)]
555pub struct VisualizationNode {
556 pub id: String,
558 pub label: String,
560 pub node_type: String,
562 pub properties: HashMap<String, String>,
564}
565
566#[derive(Debug, Clone, Serialize, Deserialize)]
568pub struct VisualizationEdge {
569 pub source: String,
571 pub target: String,
573 pub label: String,
575 pub edge_type: String,
577 pub properties: HashMap<String, String>,
579}
580
581#[derive(Debug, Clone, Serialize, Deserialize)]
587pub struct WasmPlayground {
588 pub html_template: String,
590 pub javascript_code: String,
592 pub css_styling: String,
594 pub rust_code: String,
596 pub build_instructions: Vec<String>,
598}
599
600#[derive(Debug, Clone, Serialize, Deserialize)]
602pub struct WasmBinding {
603 pub rust_name: String,
605 pub js_name: String,
607 pub methods: Vec<WasmMethod>,
609 pub examples: Vec<String>,
611}
612
613#[derive(Debug, Clone, Serialize, Deserialize)]
615pub struct WasmMethod {
616 pub name: String,
618 pub js_signature: String,
620 pub description: String,
622}
623
624#[derive(Debug, Clone, Serialize, Deserialize)]
626pub struct UIComponent {
627 pub name: String,
629 pub component_type: UIComponentType,
631 pub props: Vec<(String, String)>,
633 pub template: String,
635}
636
637#[derive(Debug, Clone, Serialize, Deserialize)]
639pub enum UIComponentType {
640 CodeEditor,
641 OutputPanel,
642 ApiExplorer,
643 ExampleGallery,
644 SearchBox,
645 NavigationMenu,
646}
647
648#[derive(Debug, Clone, Serialize, Deserialize)]
654pub struct SearchIndex {
655 pub items: Vec<SearchItem>,
657 pub metadata: SearchMetadata,
659}
660
661impl SearchIndex {
662 pub fn new() -> Self {
664 Self {
665 items: Vec::new(),
666 metadata: SearchMetadata::default(),
667 }
668 }
669
670 pub fn add_item(&mut self, item: SearchItem) -> Result<()> {
672 self.items.push(item);
673 self.metadata.total_items += 1;
674 Ok(())
675 }
676
677 pub fn search(&self, query: &str) -> Vec<&SearchItem> {
679 self.items
680 .iter()
681 .filter(|item| {
682 item.name.to_lowercase().contains(&query.to_lowercase())
683 || item
684 .description
685 .to_lowercase()
686 .contains(&query.to_lowercase())
687 || item
688 .keywords
689 .iter()
690 .any(|keyword| keyword.to_lowercase().contains(&query.to_lowercase()))
691 })
692 .collect()
693 }
694}
695
696impl Default for SearchIndex {
697 fn default() -> Self {
698 Self::new()
699 }
700}
701
702#[derive(Debug, Clone, Serialize, Deserialize)]
704pub struct SearchItem {
705 pub name: String,
707 pub item_type: SearchItemType,
709 pub description: String,
711 pub path: String,
713 pub keywords: Vec<String>,
715 pub relevance_score: f64,
717}
718
719#[derive(Debug, Clone, Serialize, Deserialize)]
721pub enum SearchItemType {
722 Trait,
723 Type,
724 Method,
725 Function,
726 Example,
727 Tutorial,
728 Documentation,
729}
730
731#[derive(Debug, Clone, Serialize, Deserialize)]
733pub struct SearchMetadata {
734 pub total_items: usize,
736 pub created_at: String,
738 pub updated_at: String,
740 pub version: String,
742}
743
744impl Default for SearchMetadata {
745 fn default() -> Self {
746 let now = chrono::Utc::now().to_string();
747 Self {
748 total_items: 0,
749 created_at: now.clone(),
750 updated_at: now,
751 version: "1.0.0".to_string(),
752 }
753 }
754}
755
756#[derive(Debug, Clone, Serialize, Deserialize)]
758pub struct EnhancedSearchIndex {
759 pub semantic_search: SemanticSearchEngine,
761 pub type_based_search: TypeSearchEngine,
763 pub usage_pattern_search: UsagePatternSearchEngine,
765 pub similarity_search: SimilaritySearchEngine,
767 pub auto_complete_engine: AutoCompleteEngine,
769 pub search_analytics: SearchAnalytics,
771}
772
773#[derive(Debug, Clone, Serialize, Deserialize)]
775pub struct SemanticSearchEngine {
776 pub index: HashMap<String, Vec<f64>>,
778 pub model_config: SemanticModelConfig,
780}
781
782impl SemanticSearchEngine {
783 pub fn new() -> Self {
785 Self {
786 index: HashMap::new(),
787 model_config: SemanticModelConfig::default(),
788 }
789 }
790
791 pub fn index_trait(&mut self, trait_info: &TraitInfo) -> Result<()> {
793 let embedding = vec![0.0; 128]; self.index.insert(trait_info.name.clone(), embedding);
796 Ok(())
797 }
798
799 pub fn index_example(&mut self, example: &CodeExample) -> Result<()> {
801 let embedding = vec![0.0; 128]; self.index.insert(example.title.clone(), embedding);
804 Ok(())
805 }
806}
807
808impl Default for SemanticSearchEngine {
809 fn default() -> Self {
810 Self::new()
811 }
812}
813
814#[derive(Debug, Clone, Serialize, Deserialize)]
816pub struct SemanticModelConfig {
817 pub model_name: String,
819 pub embedding_dim: usize,
821 pub similarity_threshold: f64,
823}
824
825impl Default for SemanticModelConfig {
826 fn default() -> Self {
827 Self {
828 model_name: "sentence-transformers/all-MiniLM-L6-v2".to_string(),
829 embedding_dim: 384,
830 similarity_threshold: 0.7,
831 }
832 }
833}
834
835#[derive(Debug, Clone, Serialize, Deserialize)]
837pub struct TypeSearchEngine {
838 pub signatures: HashMap<String, TypeSignature>,
840 pub compatibility_matrix: HashMap<String, Vec<String>>,
842}
843
844impl TypeSearchEngine {
845 pub fn new() -> Self {
847 Self {
848 signatures: HashMap::new(),
849 compatibility_matrix: HashMap::new(),
850 }
851 }
852
853 pub fn index_trait_signatures(&mut self, trait_info: &TraitInfo) -> Result<()> {
855 for method in &trait_info.methods {
856 self.signatures.insert(
857 method.name.clone(),
858 TypeSignature {
859 signature: method.signature.clone(),
860 return_type: method.return_type.clone(),
861 parameters: method.parameters.clone(),
862 },
863 );
864 }
865 Ok(())
866 }
867
868 pub fn index_type_definition(&mut self, type_info: &TypeInfo) -> Result<()> {
870 self.compatibility_matrix
872 .insert(type_info.name.clone(), type_info.trait_impls.clone());
873 Ok(())
874 }
875}
876
877impl Default for TypeSearchEngine {
878 fn default() -> Self {
879 Self::new()
880 }
881}
882
883#[derive(Debug, Clone, Serialize, Deserialize)]
885pub struct TypeSignature {
886 pub signature: String,
888 pub return_type: String,
890 pub parameters: Vec<ParameterInfo>,
892}
893
894#[derive(Debug, Clone, Serialize, Deserialize)]
896pub struct UsagePatternSearchEngine {
897 pub patterns: HashMap<String, UsagePattern>,
899 pub frequency: HashMap<String, usize>,
901}
902
903impl UsagePatternSearchEngine {
904 pub fn new() -> Self {
906 Self {
907 patterns: HashMap::new(),
908 frequency: HashMap::new(),
909 }
910 }
911
912 pub fn index_usage_patterns(&mut self, example: &CodeExample) -> Result<()> {
914 let pattern = UsagePattern {
916 pattern_type: PatternType::FunctionCall,
917 code_snippet: example.code.clone(),
918 frequency: 1,
919 confidence: 0.8,
920 };
921 self.patterns.insert(example.title.clone(), pattern);
922 Ok(())
923 }
924}
925
926impl Default for UsagePatternSearchEngine {
927 fn default() -> Self {
928 Self::new()
929 }
930}
931
932#[derive(Debug, Clone, Serialize, Deserialize)]
934pub struct UsagePattern {
935 pub pattern_type: PatternType,
937 pub code_snippet: String,
939 pub frequency: usize,
941 pub confidence: f64,
943}
944
945#[derive(Debug, Clone, Serialize, Deserialize)]
947pub enum PatternType {
948 FunctionCall,
949 MethodChaining,
950 ErrorHandling,
951 Initialization,
952 Configuration,
953}
954
955#[derive(Debug, Clone, Serialize, Deserialize)]
957pub struct SimilaritySearchEngine {
958 pub similarity_matrix: HashMap<String, HashMap<String, f64>>,
960 pub algorithms: Vec<SimilarityAlgorithm>,
962}
963
964impl SimilaritySearchEngine {
965 pub fn new() -> Self {
967 Self {
968 similarity_matrix: HashMap::new(),
969 algorithms: vec![SimilarityAlgorithm::Cosine, SimilarityAlgorithm::Jaccard],
970 }
971 }
972
973 pub fn index_trait_similarities(&mut self, trait_info: &TraitInfo) -> Result<()> {
975 let similarities = HashMap::new(); self.similarity_matrix
978 .insert(trait_info.name.clone(), similarities);
979 Ok(())
980 }
981}
982
983impl Default for SimilaritySearchEngine {
984 fn default() -> Self {
985 Self::new()
986 }
987}
988
989#[derive(Debug, Clone, Serialize, Deserialize)]
991pub enum SimilarityAlgorithm {
992 Cosine,
993 Jaccard,
994 Euclidean,
995 Manhattan,
996}
997
998#[derive(Debug, Clone, Serialize, Deserialize)]
1000pub struct AutoCompleteEngine {
1001 pub completions: HashMap<String, CompletionNode>,
1003 pub stats: CompletionStats,
1005}
1006
1007impl AutoCompleteEngine {
1008 pub fn new() -> Self {
1010 Self {
1011 completions: HashMap::new(),
1012 stats: CompletionStats::default(),
1013 }
1014 }
1015
1016 pub fn add_completion(&mut self, text: &str, completion_type: CompletionType) -> Result<()> {
1018 let node = CompletionNode {
1019 text: text.to_string(),
1020 completion_type,
1021 frequency: 1,
1022 score: 1.0,
1023 };
1024 self.completions.insert(text.to_string(), node);
1025 self.stats.total_completions += 1;
1026 Ok(())
1027 }
1028
1029 pub fn get_completions(&self, prefix: &str) -> Vec<&CompletionNode> {
1031 self.completions
1032 .values()
1033 .filter(|node| node.text.starts_with(prefix))
1034 .collect()
1035 }
1036}
1037
1038impl Default for AutoCompleteEngine {
1039 fn default() -> Self {
1040 Self::new()
1041 }
1042}
1043
1044#[derive(Debug, Clone, Serialize, Deserialize)]
1046pub struct CompletionNode {
1047 pub text: String,
1049 pub completion_type: CompletionType,
1051 pub frequency: usize,
1053 pub score: f64,
1055}
1056
1057#[derive(Debug, Clone, Serialize, Deserialize)]
1059pub enum CompletionType {
1060 Trait,
1061 Type,
1062 Method,
1063 Function,
1064 Variable,
1065 Keyword,
1066}
1067
1068#[derive(Debug, Clone, Serialize, Deserialize)]
1070pub struct CompletionStats {
1071 pub total_completions: usize,
1073 pub popular_completions: Vec<String>,
1075 pub accuracy: f64,
1077}
1078
1079impl Default for CompletionStats {
1080 fn default() -> Self {
1081 Self {
1082 total_completions: 0,
1083 popular_completions: Vec::new(),
1084 accuracy: 0.0,
1085 }
1086 }
1087}
1088
1089#[derive(Debug, Clone, Serialize, Deserialize)]
1091pub struct SearchAnalytics {
1092 pub query_count: usize,
1094 pub popular_queries: Vec<String>,
1096 pub performance_metrics: SearchPerformanceMetrics,
1098}
1099
1100impl SearchAnalytics {
1101 pub fn new() -> Self {
1103 Self {
1104 query_count: 0,
1105 popular_queries: Vec::new(),
1106 performance_metrics: SearchPerformanceMetrics::default(),
1107 }
1108 }
1109}
1110
1111impl Default for SearchAnalytics {
1112 fn default() -> Self {
1113 Self::new()
1114 }
1115}
1116
1117#[derive(Debug, Clone, Serialize, Deserialize)]
1119pub struct SearchPerformanceMetrics {
1120 pub avg_search_time_ms: f64,
1122 pub success_rate: f64,
1124 pub index_size_bytes: usize,
1126}
1127
1128impl Default for SearchPerformanceMetrics {
1129 fn default() -> Self {
1130 Self {
1131 avg_search_time_ms: 0.0,
1132 success_rate: 0.0,
1133 index_size_bytes: 0,
1134 }
1135 }
1136}
1137
1138#[derive(Debug, Clone, Serialize, Deserialize)]
1144pub struct TutorialTemplate {
1145 pub name: String,
1147 pub content: String,
1149 pub variables: HashMap<String, String>,
1151 pub required_elements: Vec<String>,
1153}
1154
1155#[allow(non_snake_case)]
1160#[cfg(test)]
1161mod tests {
1162 use super::*;
1163
1164 #[test]
1165 fn test_api_reference_creation() {
1166 let api_ref = ApiReference {
1167 crate_name: "test-crate".to_string(),
1168 version: "1.0.0".to_string(),
1169 traits: Vec::new(),
1170 types: Vec::new(),
1171 examples: Vec::new(),
1172 cross_references: HashMap::new(),
1173 metadata: ApiMetadata::default(),
1174 };
1175
1176 assert_eq!(api_ref.crate_name, "test-crate");
1177 assert_eq!(api_ref.version, "1.0.0");
1178 }
1179
1180 #[test]
1181 fn test_search_index() {
1182 let mut index = SearchIndex::new();
1183 let item = SearchItem {
1184 name: "TestTrait".to_string(),
1185 item_type: SearchItemType::Trait,
1186 description: "A test trait".to_string(),
1187 path: "test::TestTrait".to_string(),
1188 keywords: vec!["test".to_string(), "trait".to_string()],
1189 relevance_score: 1.0,
1190 };
1191
1192 index.add_item(item).unwrap();
1193 assert_eq!(index.items.len(), 1);
1194 assert_eq!(index.metadata.total_items, 1);
1195
1196 let results = index.search("test");
1197 assert_eq!(results.len(), 1);
1198 assert_eq!(results[0].name, "TestTrait");
1199 }
1200
1201 #[test]
1202 fn test_trait_info_default() {
1203 let trait_info = TraitInfo::default();
1204 assert!(trait_info.name.is_empty());
1205 assert!(trait_info.methods.is_empty());
1206 assert!(trait_info.associated_types.is_empty());
1207 }
1208
1209 #[test]
1210 fn test_code_example() {
1211 let example = CodeExample {
1212 title: "Basic Usage".to_string(),
1213 description: "Shows basic usage".to_string(),
1214 code: "fn main() {}".to_string(),
1215 language: "rust".to_string(),
1216 runnable: true,
1217 expected_output: Some("Success".to_string()),
1218 };
1219
1220 assert_eq!(example.title, "Basic Usage");
1221 assert!(example.runnable);
1222 }
1223
1224 #[test]
1225 fn test_auto_complete_engine() {
1226 let mut engine = AutoCompleteEngine::new();
1227 engine
1228 .add_completion("TestTrait", CompletionType::Trait)
1229 .unwrap();
1230 engine
1231 .add_completion("TestType", CompletionType::Type)
1232 .unwrap();
1233
1234 let completions = engine.get_completions("Test");
1235 assert_eq!(completions.len(), 2);
1236
1237 let completions = engine.get_completions("TestT");
1238 assert_eq!(completions.len(), 2);
1239
1240 let completions = engine.get_completions("TestTr");
1241 assert_eq!(completions.len(), 1);
1242 assert_eq!(completions[0].text, "TestTrait");
1243 }
1244
1245 #[test]
1246 fn test_serialization() {
1247 let example = CodeExample {
1248 title: "Test".to_string(),
1249 description: "Test example".to_string(),
1250 code: "println!(\"Hello\");".to_string(),
1251 language: "rust".to_string(),
1252 runnable: true,
1253 expected_output: None,
1254 };
1255
1256 let serialized = serde_json::to_string(&example).unwrap();
1257 let deserialized: CodeExample = serde_json::from_str(&serialized).unwrap();
1258
1259 assert_eq!(example.title, deserialized.title);
1260 assert_eq!(example.code, deserialized.code);
1261 }
1262}