agentic_evolve_core/composition/
weaver.rs1use crate::types::error::EvolveResult;
4use crate::types::pattern::Pattern;
5
6#[derive(Debug, Default)]
8pub struct IntegrationWeaver;
9
10impl IntegrationWeaver {
11 pub fn new() -> Self {
12 Self
13 }
14
15 pub fn weave(&self, patterns: &[&Pattern]) -> EvolveResult<WovenResult> {
16 let mut imports = std::collections::HashSet::new();
17 let mut body_parts = Vec::new();
18
19 for pattern in patterns {
20 for line in pattern.template.lines() {
22 let trimmed = line.trim();
23 if trimmed.starts_with("use ")
24 || trimmed.starts_with("import ")
25 || trimmed.starts_with("from ")
26 || trimmed.starts_with("#include")
27 {
28 imports.insert(trimmed.to_string());
29 }
30 }
31 body_parts.push(pattern.template.clone());
32 }
33
34 let mut code = String::new();
35
36 let mut sorted_imports: Vec<_> = imports.into_iter().collect();
38 sorted_imports.sort();
39 for imp in &sorted_imports {
40 code.push_str(imp);
41 code.push('\n');
42 }
43 if !sorted_imports.is_empty() {
44 code.push('\n');
45 }
46
47 for (i, part) in body_parts.iter().enumerate() {
49 let body: String = part
51 .lines()
52 .filter(|l| {
53 let t = l.trim();
54 !t.starts_with("use ")
55 && !t.starts_with("import ")
56 && !t.starts_with("from ")
57 && !t.starts_with("#include")
58 })
59 .collect::<Vec<&str>>()
60 .join("\n");
61 code.push_str(body.trim());
62 if i < body_parts.len() - 1 {
63 code.push_str("\n\n");
64 }
65 }
66
67 Ok(WovenResult {
68 code,
69 patterns_used: patterns.iter().map(|p| p.id.as_str().to_string()).collect(),
70 import_count: sorted_imports.len(),
71 })
72 }
73}
74
75#[derive(Debug, Clone)]
77pub struct WovenResult {
78 pub code: String,
79 pub patterns_used: Vec<String>,
80 pub import_count: usize,
81}