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