diff options
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | rustfmt.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 85 |
4 files changed, 72 insertions, 22 deletions
@@ -196,6 +196,12 @@ dependencies = [ ] [[package]] +name = "humansize" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" + +[[package]] name = "instant" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -425,6 +431,7 @@ version = "0.0.1" dependencies = [ "anyhow", "hexdump", + "humansize", "rustyline", "sled", "structopt", @@ -14,3 +14,4 @@ structopt = { version = "0.3", default-features = false } hexdump = "0.1" utf-8 = "0.7" anyhow = "1.0" +humansize = "1.1" diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..218e203 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +hard_tabs = true diff --git a/src/main.rs b/src/main.rs index a2de0e1..51f8f06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,10 @@ -use std::path::PathBuf; use std::ops::Deref; +use std::path::PathBuf; use anyhow::Result; +use humansize::{file_size_opts, FileSize}; + use rustyline::error::ReadlineError; use rustyline::Editor; @@ -14,7 +16,7 @@ use sled::IVec; #[structopt(name = "sledcli")] struct Opt { /// Path to Sled database - #[structopt(name="path")] + #[structopt(name = "path")] path: PathBuf, } @@ -45,38 +47,45 @@ fn main() { }; let mut readline = Editor::<()>::new(); - loop { - let lineread = readline.readline(&format!("{}> ", try_string(&state.tree.name()))); - match lineread { - Ok(line) => { - readline.add_history_entry(line.as_str()); + loop { + let prefix = match state.displaymode { + DisplayMode::HexDump => "hex", + DisplayMode::TryString => "str", + DisplayMode::Mixed => "mix", + }; + let prompt = format!("[{}] {}> ", prefix, try_string(&state.tree.name())); + let lineread = readline.readline(&prompt); + match lineread { + Ok(line) => { + readline.add_history_entry(line.as_str()); if let Err(e) = do_command(&line, &mut state) { println!("Error: {}", e); } - }, - Err(ReadlineError::Interrupted) => { + } + Err(ReadlineError::Interrupted) => { println!("^C"); continue; - }, - Err(ReadlineError::Eof) => { - break - }, - Err(err) => { - println!("Readline error: {:?}", err); - break - } - } - } + } + Err(ReadlineError::Eof) => break, + Err(err) => { + println!("Readline error: {:?}", err); + break; + } + } + } } fn try_string(input: &sled::IVec) -> String { - let mut string = String::new(); + let mut string = String::new(); utf8::LossyDecoder::new(|s| string.push_str(s)).feed(input); string } fn do_command(line: &str, state: &mut State) -> Result<()> { - let parts = line.split(' ').filter(|part| part.len() > 0).collect::<Vec<_>>(); + let parts = line + .split(' ') + .filter(|part| part.len() > 0) + .collect::<Vec<_>>(); if parts.is_empty() { return Ok(()); } @@ -89,8 +98,40 @@ fn do_command(line: &str, state: &mut State) -> Result<()> { println!("{}", try_string(&name)); } } + ["ll"] => { + let mut names = state.db.tree_names(); + names.sort(); + for name in names { + let nent = state.db.open_tree(&name)?.len(); + println!("{:8} {}", nent, try_string(&name)); + } + } + ["lu"] => { + let mut names = state.db.tree_names(); + names.sort(); + for name in names { + let tree = state.db.open_tree(&name)?; + let nent = tree.len(); + let mut size = 0; + for ent in tree.iter() { + let (k, v) = ent?; + size += k.len() + v.len(); + } + println!( + "{:8} {:>12} {}", + nent, + size.file_size(file_size_opts::CONVENTIONAL).unwrap(), + try_string(&name) + ); + } + } ["cd", treename] => { - if state.db.tree_names().iter().any(|t| t == treename.as_bytes()) { + if state + .db + .tree_names() + .iter() + .any(|t| t == treename.as_bytes()) + { state.tree = state.db.open_tree(treename.as_bytes())?; } else { println!("Tree {} does not exist", treename); |