Skip to main content

lean_ctx/core/patterns/
swift.rs

1pub fn compress(cmd: &str, output: &str) -> Option<String> {
2    let trimmed = output.trim();
3    if trimmed.is_empty() {
4        return Some("ok".to_string());
5    }
6
7    if cmd.contains("test") {
8        return Some(compress_test(trimmed));
9    }
10    if cmd.contains("build") {
11        return Some(compress_build(trimmed));
12    }
13    if cmd.contains("package resolve") || cmd.contains("package update") {
14        return Some(compress_resolve(trimmed));
15    }
16
17    Some(compact_lines(trimmed, 15))
18}
19
20fn compress_test(output: &str) -> String {
21    let mut passed = 0u32;
22    let mut failed = 0u32;
23    let mut failures = Vec::new();
24    let mut time = String::new();
25
26    for line in output.lines() {
27        let trimmed = line.trim();
28        if trimmed.contains("Test Case") && trimmed.contains("passed") {
29            passed += 1;
30        } else if trimmed.contains("Test Case") && trimmed.contains("failed") {
31            failed += 1;
32            failures.push(trimmed.to_string());
33        }
34        if trimmed.starts_with("Test Suite") && trimmed.contains("Executed") {
35            time = trimmed.to_string();
36        }
37        if trimmed.contains("Executed")
38            && trimmed.contains("tests")
39            && let Some(pos) = trimmed.find("Executed")
40        {
41            time = trimmed[pos..].to_string();
42        }
43    }
44
45    if passed == 0 && failed == 0 {
46        return compact_lines(output, 10);
47    }
48
49    let mut result = format!("swift test: {passed} passed");
50    if failed > 0 {
51        result.push_str(&format!(", {failed} failed"));
52    }
53    if !time.is_empty() {
54        result.push_str(&format!("\n  {time}"));
55    }
56    for f in failures.iter().take(5) {
57        result.push_str(&format!("\n  FAIL: {f}"));
58    }
59    result
60}
61
62fn compress_build(output: &str) -> String {
63    let mut compiling = 0u32;
64    let mut linking = false;
65    let mut errors = Vec::new();
66    let mut warnings = 0u32;
67
68    for line in output.lines() {
69        let trimmed = line.trim();
70        if trimmed.starts_with("Compiling") || trimmed.contains('[') && trimmed.contains(']') {
71            compiling += 1;
72        }
73        if trimmed.starts_with("Linking") || trimmed.contains("Linking") {
74            linking = true;
75        }
76        if trimmed.contains("error:") {
77            errors.push(trimmed.to_string());
78        }
79        if trimmed.contains("warning:") {
80            warnings += 1;
81        }
82    }
83
84    if !errors.is_empty() {
85        let mut result = format!("{} errors", errors.len());
86        if warnings > 0 {
87            result.push_str(&format!(", {warnings} warnings"));
88        }
89        for e in errors.iter().take(10) {
90            result.push_str(&format!("\n  {e}"));
91        }
92        return result;
93    }
94
95    let mut result = format!("Build ok ({compiling} compiled");
96    if linking {
97        result.push_str(", linked");
98    }
99    if warnings > 0 {
100        result.push_str(&format!(", {warnings} warnings"));
101    }
102    result.push(')');
103    result
104}
105
106fn compress_resolve(output: &str) -> String {
107    let mut fetched = 0u32;
108    let mut resolved = 0u32;
109    for line in output.lines() {
110        if line.contains("Fetching") {
111            fetched += 1;
112        }
113        if line.contains("Resolving") || line.contains("resolved") {
114            resolved += 1;
115        }
116    }
117    if fetched == 0 && resolved == 0 {
118        return compact_lines(output, 5);
119    }
120    format!("{fetched} fetched, {resolved} resolved")
121}
122
123fn compact_lines(text: &str, max: usize) -> String {
124    let lines: Vec<&str> = text.lines().filter(|l| !l.trim().is_empty()).collect();
125    if lines.len() <= max {
126        return lines.join("\n");
127    }
128    format!(
129        "{}\n... ({} more lines)",
130        lines[..max].join("\n"),
131        lines.len() - max
132    )
133}