Skip to main content

lean_ctx/core/patterns/
prisma.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("generate") {
8        return Some(compress_generate(trimmed));
9    }
10    if cmd.contains("migrate") {
11        return Some(compress_migrate(trimmed));
12    }
13    if cmd.contains("db push") || cmd.contains("db pull") {
14        return Some(compress_db_sync(trimmed));
15    }
16    if cmd.contains("studio") {
17        return Some("Prisma Studio started".to_string());
18    }
19    if cmd.contains("format") {
20        return Some(compress_format(trimmed));
21    }
22    if cmd.contains("validate") {
23        return Some(compress_validate(trimmed));
24    }
25
26    Some(compact_lines(trimmed, 10))
27}
28
29fn compress_generate(output: &str) -> String {
30    let mut generated = Vec::new();
31    for line in output.lines() {
32        let trimmed = line.trim();
33        let plain = strip_ansi(trimmed);
34        if plain.contains("Generated") || plain.contains("generated") {
35            generated.push(plain);
36        }
37    }
38    if generated.is_empty() {
39        return strip_noise(output);
40    }
41    generated.join("\n")
42}
43
44fn compress_migrate(output: &str) -> String {
45    let mut results = Vec::new();
46    let mut migration_name = String::new();
47
48    for line in output.lines() {
49        let plain = strip_ansi(line.trim());
50        if plain.contains("migration") && plain.contains("created") {
51            migration_name = plain.clone();
52        }
53        if plain.contains("applied")
54            || plain.contains("Already in sync")
55            || plain.contains("Database is up to date")
56        {
57            results.push(plain);
58        }
59    }
60
61    if results.is_empty() && migration_name.is_empty() {
62        return strip_noise(output);
63    }
64
65    let mut parts = Vec::new();
66    if !migration_name.is_empty() {
67        parts.push(migration_name);
68    }
69    parts.extend(results);
70    parts.join("\n")
71}
72
73fn compress_db_sync(output: &str) -> String {
74    let lines: Vec<String> = output
75        .lines()
76        .map(|l| strip_ansi(l.trim()))
77        .filter(|l| !l.is_empty() && !l.contains("warn") && !l.starts_with("Prisma schema"))
78        .collect();
79
80    if lines.is_empty() {
81        return "ok (synced)".to_string();
82    }
83    lines.join("\n")
84}
85
86fn compress_format(output: &str) -> String {
87    if output.contains("already formatted") || output.contains("unchanged") {
88        return "ok (already formatted)".to_string();
89    }
90    strip_noise(output)
91}
92
93fn compress_validate(output: &str) -> String {
94    let plain = strip_ansi(output.trim());
95    if plain.contains("valid") && !plain.contains("invalid") {
96        return "ok (schema valid)".to_string();
97    }
98    compact_lines(&plain, 10)
99}
100
101fn strip_noise(output: &str) -> String {
102    output
103        .lines()
104        .map(|l| strip_ansi(l.trim()))
105        .filter(|l| !l.is_empty() && !l.contains("████") && !l.contains("▀") && !l.contains("━"))
106        .collect::<Vec<_>>()
107        .join("\n")
108}
109
110fn strip_ansi(s: &str) -> String {
111    let mut result = String::with_capacity(s.len());
112    let mut in_escape = false;
113    for c in s.chars() {
114        if c == '\x1b' {
115            in_escape = true;
116        } else if in_escape {
117            if c.is_ascii_alphabetic() {
118                in_escape = false;
119            }
120        } else {
121            result.push(c);
122        }
123    }
124    result
125}
126
127fn compact_lines(text: &str, max: usize) -> String {
128    let lines: Vec<&str> = text.lines().filter(|l| !l.trim().is_empty()).collect();
129    if lines.len() <= max {
130        return lines.join("\n");
131    }
132    format!(
133        "{}\n... ({} more lines)",
134        lines[..max].join("\n"),
135        lines.len() - max
136    )
137}