From c1e04fc9c5bf92365cc119d906b33b9845f93e4d Mon Sep 17 00:00:00 2001 From: Andrew Phillips Date: Tue, 6 May 2025 11:00:35 -0300 Subject: [PATCH] feat: add diff mode to compare items --- src/main.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6b1dea2..fb28c92 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,7 @@ extern crate lazy_static; pub mod compression; pub mod db; +//pub mod item; use compression::CompressionType; use compression::program::CompressionEngineProgram; @@ -87,31 +88,35 @@ struct Args { #[derive(Parser, Debug)] struct ModeArgs { - #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["get", "list", "update", "delete", "info", "status"]))] + #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["get", "diff", "list", "update", "delete", "info", "status"]))] #[arg(help("Save an item using any tags or metadata provided"))] save: bool, - #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "list", "update", "delete", "info", "status"]))] + #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "diff", "list", "update", "delete", "info", "status"]))] #[arg(help("Get an item either by it's ID or by a combination of matching tags and metatdata"))] get: bool, - #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "get", "update", "delete", "info", "status"]))] + #[arg(group("mode"), help_heading("Mode Options"), long, conflicts_with_all(["save", "get", "list", "update", "delete", "info", "status"]))] + #[arg(help("Show a diff between two items by ID"))] + diff: bool, + + #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "get", "diff", "update", "delete", "info", "status"]))] #[arg(help("List items, filtering on tags or metadata if given"))] list: bool, - #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "get", "list", "delete", "info", "status"]), requires("ids_or_tags"))] + #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "get", "diff", "list", "delete", "info", "status"]), requires("ids_or_tags"))] #[arg(help("Update a specified item ID's tags and/or metadata"))] update: bool, - #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "get", "list", "update", "info", "status"]), requires("ids_or_tags"))] + #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "get", "diff", "list", "update", "info", "status"]), requires("ids_or_tags"))] #[arg(help("Delete items either by ID or by matching tags"))] delete: bool, - #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "get", "list", "update", "delete", "status"]), requires("ids_or_tags"))] + #[arg(group("mode"), help_heading("Mode Options"), short, long, conflicts_with_all(["save", "get", "diff", "list", "update", "delete", "status"]), requires("ids_or_tags"))] #[arg(help("Get an item either by it's ID or by a combination of matching tags and metatdata"))] info: bool, - #[arg(group("mode"), help_heading("Mode Options"), short('S'), long, conflicts_with_all(["save", "get", "list", "update", "delete", "info"]))] + #[arg(group("mode"), help_heading("Mode Options"), short('S'), long, conflicts_with_all(["save", "get", "diff", "list", "update", "delete", "info"]))] #[arg(help("Show status of directories and supported compression algorithms"))] status: bool } @@ -148,7 +153,7 @@ struct OptionsArgs { verbose: u8, #[arg(short, long)] - #[arg(help("Do show any messages"))] + #[arg(help("Do not show any messages"))] quiet: bool, } @@ -158,6 +163,7 @@ enum KeepModes { Unknown, Save, Get, + Diff, List, Update, Delete, @@ -248,6 +254,8 @@ fn main() -> Result<(), Error> { mode = KeepModes::Save; } else if args.mode.get { mode = KeepModes::Get; + } else if args.mode.diff { + mode = KeepModes::Diff; } else if args.mode.list { mode = KeepModes::List; } else if args.mode.delete { @@ -302,6 +310,7 @@ fn main() -> Result<(), Error> { match mode { KeepModes::Save => mode_save(&mut cmd, args, ids, tags, conn, data_path)?, KeepModes::Get => mode_get(&mut cmd, args, ids, tags, &mut conn, data_path)?, + KeepModes::Diff => mode_diff(&mut cmd, args, ids, tags, &mut conn, data_path)?, KeepModes::List => mode_list(&mut cmd, args, ids, tags, &mut conn, data_path)?, KeepModes::Update => mode_update(&mut cmd, args, ids, tags, &mut conn, data_path)?, KeepModes::Info => mode_info(&mut cmd, args, ids, tags, &mut conn, data_path)?, @@ -470,6 +479,56 @@ fn mode_get(cmd: &mut Command, args: Args, ids: &mut Vec, tags: &mut Vec, tags: &mut Vec, conn: &mut Connection, data_path: PathBuf) -> Result<()> { + + if ! tags.is_empty() { + cmd.error(ErrorKind::InvalidValue, "Tags given, you must supply exactly two IDs when using --diff").exit(); + } else if ids.len() > 2 || ids.len() < 1 { + cmd.error(ErrorKind::InvalidValue, "You must supply exactly one or two IDs when using --diff").exit(); + } + + let item_a: Option = db::get_item(conn, ids[0])?; + + let mut item_b: Option = None; + if ids.len() == 2 { + item_b = db::get_item(conn, ids[1])?; + } + + if let Some(item_a) = item_a { + debug!("MAIN: Found item A {:?}", item_a); + + let mut item_path_a = data_path.clone(); + item_path_a.push(item_a.id.unwrap().to_string()); + + let compression_type_a = CompressionType::from_str(&item_a.compression)?; + debug!("MAIN: Item A has compression type {:?}", compression_type_a.clone()); + + let compression_engine_a = compression::get_engine(compression_type_a).expect("Unable to get compression engine"); + + if let Some(item_b) = item_b { + debug!("MAIN: Found item B {:?}", item_b); + + let mut item_path_b = data_path.clone(); + item_path_b.push(item_b.id.unwrap().to_string()); + + let compression_type_b = CompressionType::from_str(&item_b.compression)?; + debug!("MAIN: Item B has compression type {:?}", compression_type_b.clone()); + + let compression_engine_b = compression::get_engine(compression_type_b).expect("Unable to get compression engine"); + + let program = "diff"; + let args = ["-u"]; + + Ok(()) + } else { + Err(anyhow!("Unable to find second item in database")) + } + } else { + Err(anyhow!("Unable to find first item in database")) + } +} + + fn mode_list(cmd: &mut Command, args: Args, ids: &mut Vec, tags: &Vec, conn: &mut Connection, data_path: PathBuf) -> Result<()> { if ! ids.is_empty() { cmd.error(ErrorKind::InvalidValue, "ID given, you can only supply tags when using --list").exit(); @@ -907,7 +966,6 @@ fn format_size_human_readable(size: u64) -> String { humansize::format_size(size, options) } - fn format_size(size: u64, human_readable: bool) -> String { match human_readable { true => format_size_human_readable(size),