diff --git a/Cargo.lock b/Cargo.lock index 3df1486..77186a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,6 +122,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "env_filter" version = "0.1.3" @@ -245,6 +251,7 @@ name = "nix-diff" version = "0.1.0" dependencies = [ "clap", + "diff", "env_logger", "log", "regex", diff --git a/Cargo.toml b/Cargo.toml index f7a9fed..e27aec3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ thiserror = "2.0.12" log = "0.4.20" env_logger = "0.11.3" rusqlite = { version = "0.35.0", features = ["bundled"] } +diff = "0.1.13" diff --git a/src/print.rs b/src/print.rs index 816689c..ee00a87 100644 --- a/src/print.rs +++ b/src/print.rs @@ -2,6 +2,35 @@ use core::str; use std::collections::{HashMap, HashSet}; use yansi::Paint; +fn diff_versions(left: &str, right: &str) -> (String, String) { + let mut prev = String::new(); + let mut post = String::new(); + + for diff in diff::chars(left, right) { + match diff { + diff::Result::Both(l, _) => { + prev.push(l); + post.push(l); + } + diff::Result::Left(l) => { + let string_to_push = format!("\x1b[31m{l}"); + prev.push_str(&string_to_push); + } + + diff::Result::Right(r) => { + let string_to_push = format!("\x1b[32m{r}"); + post.push_str(&string_to_push); + } + } + } + + //reset + prev.push_str("\x1b[0m"); + post.push_str("\x1b[0m"); + + (prev, post) +} + pub fn print_added(set: HashSet<&str>, post: &HashMap<&str, HashSet<&str>>, col_width: usize) { println!("{}", "Packages added:".underline().bold()); @@ -23,7 +52,7 @@ pub fn print_added(set: HashSet<&str>, post: &HashMap<&str, HashSet<&str>>, col_ "A:".green().bold(), p, "@".yellow().bold(), - version_str.blue() + version_str ); } } @@ -49,7 +78,7 @@ pub fn print_removed(set: HashSet<&str>, pre: &HashMap<&str, HashSet<&str>>, col "R:".red().bold(), p, "@".yellow(), - version_str.blue() + version_str ); } } @@ -78,20 +107,38 @@ pub fn print_changes( for (p, ver_pre, ver_post) in changes { let mut version_vec_pre = ver_pre.iter().copied().collect::>(); - version_vec_pre.sort_unstable(); - let version_str_pre = version_vec_pre.join(", "); let mut version_vec_post = ver_post.iter().copied().collect::>(); + version_vec_pre.sort_unstable(); version_vec_post.sort_unstable(); - let version_str_post = version_vec_post.join(", "); + + let diffed_pre: String; + let diffed_post: String; + + if version_vec_pre.len() == version_vec_post.len() { + let mut diff_pre: Vec = vec![]; + let mut diff_post: Vec = vec![]; + + for (pre, post) in version_vec_pre.iter().zip(version_vec_post.iter()) { + let (a, b) = diff_versions(pre, post); + diff_pre.push(a); + diff_post.push(b); + } + diffed_pre = diff_pre.join(", "); + diffed_post = diff_post.join(", "); + } else { + let version_str_pre = version_vec_pre.join(", "); + let version_str_post = version_vec_post.join(", "); + (diffed_pre, diffed_post) = diff_versions(&version_str_pre, &version_str_post); + } println!( "[{}] {:col_width$} {} {} ~> {}", "C:".bold().bright_yellow(), p, "@".yellow(), - version_str_pre.magenta(), - version_str_post.blue() + diffed_pre, + diffed_post ); } }