From b184c35e2eb6ef951f78fd61f3e35e15c6e549ae Mon Sep 17 00:00:00 2001 From: Erik Grinaker Date: Sun, 21 Jul 2024 22:09:49 +0200 Subject: [PATCH] bin: clean up `toydump` command --- src/bin/toydump.rs | 66 +++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/src/bin/toydump.rs b/src/bin/toydump.rs index 41e433980..a487800e5 100644 --- a/src/bin/toydump.rs +++ b/src/bin/toydump.rs @@ -1,38 +1,50 @@ //! toydump is a debug tool that prints a toyDB BitCask database in -//! human-readable form. It only prints live BitCask data, not garbage entries. +//! human-readable form. It can print both the SQL database, and the Raft log +//! (via --raft). It only outputs live BitCask data, not garbage entries. + #![warn(clippy::all)] use toydb::encoding::format::{self, Formatter as _}; use toydb::error::Result; use toydb::storage::{BitCask, Engine as _}; -fn main() -> Result<()> { - let args = clap::command!() - .about("Prints toyDB file contents in human-readable form.") - .args([ - clap::Arg::new("raft") - .long("raft") - .num_args(0) - .help("file is a Raft log, not SQL database"), - clap::Arg::new("raw").long("raw").num_args(0).help("also show raw key/value"), - clap::Arg::new("file").required(true), - ]) - .get_matches(); - let raft: bool = *args.get_one("raft").unwrap(); - let raw: bool = *args.get_one("raw").unwrap(); - let file: &String = args.get_one("file").unwrap(); +use clap::Parser as _; + +fn main() { + if let Err(error) = Command::parse().run() { + eprintln!("Error: {error}") + } +} + +/// The toydump command. +#[derive(clap::Parser)] +#[command(about = "Prints toyDB file contents.", version, propagate_version = true)] +struct Command { + /// The BitCask file to dump (SQL database unless --raft). + file: String, + /// The file is a Raft log, not SQL database. + #[arg(long)] + raft: bool, + /// Also show raw key and value. + #[arg(long)] + raw: bool, +} - let mut engine = BitCask::new(file.into())?; - let mut scan = engine.scan(..); - while let Some((key, value)) = scan.next().transpose()? { - let mut string = match raft { - true => format::Raft::::key_value(&key, &value), - false => format::MVCC::::key_value(&key, &value), - }; - if raw { - string = format!("{string} [{}]", format::Raw::key_value(&key, &value)) +impl Command { + /// Runs the command. + fn run(self) -> Result<()> { + let mut engine = BitCask::new(self.file.into())?; + let mut scan = engine.scan(..); + while let Some((key, value)) = scan.next().transpose()? { + let mut string = match self.raft { + true => format::Raft::::key_value(&key, &value), + false => format::MVCC::::key_value(&key, &value), + }; + if self.raw { + string = format!("{string} [{}]", format::Raw::key_value(&key, &value)) + } + println!("{string}"); } - println!("{string}"); + Ok(()) } - Ok(()) }