lean_ctx/core/patterns/
zig.rs1pub 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
14 Some(compact_lines(trimmed, 15))
15}
16
17fn compress_test(output: &str) -> String {
18 let mut passed = 0u32;
19 let mut failed = 0u32;
20 let mut failures = Vec::new();
21
22 for line in output.lines() {
23 let trimmed = line.trim();
24 if trimmed.contains("1/1 test") || trimmed.contains("test passed") {
25 passed += 1;
26 }
27 if trimmed.contains("FAIL") || trimmed.contains("test failed") {
28 failed += 1;
29 failures.push(trimmed.to_string());
30 }
31 if trimmed.contains("All") && trimmed.contains("passed") {
32 if let Some(n) = trimmed
33 .split_whitespace()
34 .nth(1)
35 .and_then(|w| w.parse().ok())
36 {
37 passed = n;
38 }
39 }
40 }
41
42 if passed == 0 && failed == 0 {
43 return compact_lines(output, 10);
44 }
45
46 let mut result = format!("zig test: {passed} passed");
47 if failed > 0 {
48 result.push_str(&format!(", {failed} failed"));
49 }
50 for f in failures.iter().take(5) {
51 result.push_str(&format!("\n {f}"));
52 }
53 result
54}
55
56fn compress_build(output: &str) -> String {
57 let errors: Vec<&str> = output
58 .lines()
59 .filter(|l| l.contains("error:") || l.contains("Error"))
60 .collect();
61 let warnings: Vec<&str> = output.lines().filter(|l| l.contains("warning:")).collect();
62
63 if !errors.is_empty() {
64 let mut result = format!("{} errors", errors.len());
65 if !warnings.is_empty() {
66 result.push_str(&format!(", {} warnings", warnings.len()));
67 }
68 for e in errors.iter().take(10) {
69 result.push_str(&format!("\n {}", e.trim()));
70 }
71 return result;
72 }
73
74 if !warnings.is_empty() {
75 return format!("ok ({} warnings)", warnings.len());
76 }
77
78 "ok".to_string()
79}
80
81fn compact_lines(text: &str, max: usize) -> String {
82 let lines: Vec<&str> = text.lines().filter(|l| !l.trim().is_empty()).collect();
83 if lines.len() <= max {
84 return lines.join("\n");
85 }
86 format!(
87 "{}\n... ({} more lines)",
88 lines[..max].join("\n"),
89 lines.len() - max
90 )
91}