use anyhow::{bail, Result};
use std::io::Write;
use crate::config;
use crate::db::{self, CommandRecord};
pub fn run_show(id: i64) -> Result<()> {
let conn = db::open(&config::db_path()?)?;
match db::get_command(&conn, id)? {
Some(record) => {
let stdout = std::io::stdout();
let mut out = stdout.lock();
write!(out, "{}", format_record(&record))?;
Ok(())
}
None => bail!("Aucune commande avec l'ID {id}."),
}
}
pub fn run_print(id: i64) -> Result<()> {
let conn = db::open(&config::db_path()?)?;
match db::get_command(&conn, id)? {
Some(record) => {
let stdout = std::io::stdout();
let mut out = stdout.lock();
writeln!(out, "{}", record.command)?;
Ok(())
}
None => bail!("Aucune commande avec l'ID {id}."),
}
}
fn format_record(r: &CommandRecord) -> String {
let mut out = String::new();
out.push_str(&format!("Commande {}\n\n", r.id));
out.push_str(&format!("Date : {}\n", r.created_at));
if let Some(cwd) = field(&r.cwd) {
out.push_str(&format!("Dossier : {cwd}\n"));
}
if let Some(root) = field(&r.git_root) {
out.push_str(&format!("Projet Git : {root}\n"));
}
if let Some(branch) = field(&r.git_branch) {
out.push_str(&format!("Branche : {branch}\n"));
}
if let Some(remote) = field(&r.git_remote) {
out.push_str(&format!("Remote : {remote}\n"));
}
if let Some(shell) = field(&r.shell) {
out.push_str(&format!("Shell : {shell}\n"));
}
if let Some(session) = field(&r.session_id) {
out.push_str(&format!("Session : {session}\n"));
}
if let Some(code) = r.exit_code {
out.push_str(&format!("Code retour : {code}\n"));
}
out.push_str(&format!("\nCommande :\n{}\n", r.command));
out
}
fn field(value: &Option<String>) -> Option<&str> {
value.as_deref().filter(|s| !s.trim().is_empty())
}
#[cfg(test)]
mod tests {
use super::*;
fn rec() -> CommandRecord {
CommandRecord {
id: 128,
command: "cargo test --locked".to_string(),
cwd: Some("/home/u/projects/mnemo".to_string()),
shell: Some("bash".to_string()),
hostname: None,
exit_code: Some(0),
created_at: "2026-06-23 14:22:10".to_string(),
git_root: Some("/home/u/projects/mnemo".to_string()),
git_branch: Some("main".to_string()),
git_remote: None,
session_id: Some("20260623T141200-12345".to_string()),
}
}
#[test]
fn format_affiche_les_champs_disponibles() {
let out = format_record(&rec());
assert!(out.contains("Commande 128"));
assert!(out.contains("Date : 2026-06-23 14:22:10"));
assert!(out.contains("Dossier : /home/u/projects/mnemo"));
assert!(out.contains("Projet Git : /home/u/projects/mnemo"));
assert!(out.contains("Branche : main"));
assert!(out.contains("Session : 20260623T141200-12345"));
assert!(out.contains("Code retour : 0"));
assert!(out.contains("Commande :\ncargo test --locked\n"));
}
#[test]
fn format_omet_les_champs_absents() {
let mut r = rec();
r.git_remote = None;
r.git_branch = None;
r.session_id = None;
r.git_root = Some(" ".to_string()); let out = format_record(&r);
assert!(!out.contains("Branche :"));
assert!(!out.contains("Remote :"));
assert!(!out.contains("Session :"));
assert!(!out.contains("Projet Git :"));
}
#[test]
fn format_preserve_une_commande_redactee() {
let mut r = rec();
r.command = "curl -H 'Authorization: Bearer [REDACTED]'".to_string();
let out = format_record(&r);
assert!(out.contains("[REDACTED]"));
}
}