mod cli;
mod commands;
mod db;
mod error;
mod repl;
mod validator;
use anyhow::Result;
use clap::Parser;
use colored::*;
use cli::Args;
use db::SledViewer;
use error::SledoViewError;
use repl::Repl;
use validator::DatabaseValidator;
fn main() -> Result<()> {
let args = Args::parse();
println!(
"{}",
"SledoView - SLED Database Viewer".bright_cyan().bold()
);
println!("{}", "═".repeat(35).bright_cyan());
if args.database_path.to_string_lossy() == "create-test" {
create_test_database()?;
return Ok(());
}
let validator = DatabaseValidator::new(&args.database_path);
if let Err(e) = validator.validate() {
startup_error_and_exit(e);
}
let viewer = match SledViewer::new(&args.database_path) {
Ok(v) => v,
Err(e) => startup_error_and_exit(e),
};
if !viewer.is_writable() {
println!(
"{} {}",
"⚠".bright_yellow().bold(),
"Database opened in read-only mode (write operations will fail)".bright_yellow()
);
}
println!(
"{} {}",
"✓".bright_green().bold(),
format!(
"Successfully opened database: {}",
args.database_path.display()
)
.bright_green()
);
let mut repl = Repl::new(viewer);
repl.run()?;
Ok(())
}
fn startup_error_and_exit(err: anyhow::Error) -> ! {
let is_locked = err
.downcast_ref::<SledoViewError>()
.is_some_and(|e| matches!(e, SledoViewError::DatabaseLocked { .. }));
if is_locked {
eprintln!(
"\n{} {}",
"✗ Database is locked.".bright_red().bold(),
"Another process has it open.".red()
);
eprintln!(
" {}",
"Close the other application and try again.".yellow()
);
} else {
eprintln!(
"\n{} {}",
"✗ Failed to open database:".bright_red().bold(),
err.to_string().red()
);
}
std::process::exit(1);
}
fn create_test_database() -> Result<()> {
println!("Creating test database...");
let db = sled::open("test.db")?;
db.insert("user_1", "Alice Smith")?;
db.insert("user_2", "Bob Johnson")?;
db.insert("config_timeout", "30")?;
db.insert("config_debug", "true")?;
db.insert("data_large", "This is a longer text value that should be truncated in the preview display to demonstrate the truncation feature")?;
db.insert("empty_key", "")?;
db.insert("binary_data", &[0u8, 1u8, 2u8, 255u8])?;
db.flush()?;
println!("✓ Test database 'test.db' created successfully!");
println!("You can now run: {}", "cargo run test.db".bright_yellow());
Ok(())
}