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