systemprompt_database/services/
display.rs1use std::io::Write;
2
3use crate::models::{ColumnInfo, DatabaseInfo, QueryResult, TableInfo};
4
5pub trait DatabaseCliDisplay {
6 fn display_with_cli(&self);
7}
8
9fn stdout_writeln(args: std::fmt::Arguments<'_>) {
10 let mut stdout = std::io::stdout();
11 let _ = writeln!(stdout, "{args}");
12}
13
14impl DatabaseCliDisplay for Vec<TableInfo> {
15 fn display_with_cli(&self) {
16 if self.is_empty() {
17 stdout_writeln(format_args!("No tables found"));
18 } else {
19 stdout_writeln(format_args!("Tables:"));
20 for table in self {
21 stdout_writeln(format_args!(" {} (rows: {})", table.name, table.row_count));
22 }
23 }
24 }
25}
26
27impl DatabaseCliDisplay for (Vec<ColumnInfo>, i64) {
28 fn display_with_cli(&self) {
29 let (columns, _) = self;
30 stdout_writeln(format_args!("Columns:"));
31 for col in columns {
32 let default_display = col
33 .default
34 .as_deref()
35 .map_or_else(String::new, |d| format!("DEFAULT {d}"));
36
37 stdout_writeln(format_args!(
38 " {} {} {} {} {}",
39 col.name,
40 col.data_type,
41 if col.nullable { "NULL" } else { "NOT NULL" },
42 if col.primary_key { "PK" } else { "" },
43 default_display
44 ));
45 }
46 }
47}
48
49impl DatabaseCliDisplay for DatabaseInfo {
50 fn display_with_cli(&self) {
51 stdout_writeln(format_args!("Database Info:"));
52 stdout_writeln(format_args!(" Path: {}", self.path));
53 stdout_writeln(format_args!(" Version: {}", self.version));
54 stdout_writeln(format_args!(" Tables: {}", self.tables.len()));
55 }
56}
57
58impl DatabaseCliDisplay for QueryResult {
59 fn display_with_cli(&self) {
60 if self.columns.is_empty() {
61 stdout_writeln(format_args!("No data returned"));
62 return;
63 }
64
65 stdout_writeln(format_args!("{}", self.columns.join(" | ")));
66 stdout_writeln(format_args!("{}", "-".repeat(80)));
67
68 for row in &self.rows {
69 let values: Vec<String> = self
70 .columns
71 .iter()
72 .map(|col| {
73 row.get(col).map_or_else(
74 || "NULL".to_string(),
75 |v| match v {
76 serde_json::Value::String(s) => s.clone(),
77 serde_json::Value::Null => "NULL".to_string(),
78 serde_json::Value::Bool(_)
79 | serde_json::Value::Number(_)
80 | serde_json::Value::Array(_)
81 | serde_json::Value::Object(_) => v.to_string(),
82 },
83 )
84 })
85 .collect();
86 stdout_writeln(format_args!("{}", values.join(" | ")));
87 }
88
89 stdout_writeln(format_args!(
90 "\n{} rows returned in {}ms",
91 self.row_count, self.execution_time_ms
92 ));
93 }
94}