this repo has no description

refactor: we are now clone free

+71 -51
+28 -27
src/diff.rs
··· 14 longest_name: usize, 15 } 16 17 - pub fn partition_diff(diff: &DiffRoot) -> PackageListDiff { 18 - let mut added = BTreeMap::new(); 19 - let mut removed = BTreeMap::new(); 20 - let mut changed = BTreeMap::new(); 21 - let mut size_delta: i64 = 0; 22 - let mut longest_name = 0; 23 24 - for (name, package) in &diff.packages { 25 - match package.diff_type { 26 - DiffType::Added => { 27 - added.insert(name.clone(), package.clone()); 28 - } 29 - DiffType::Removed => { 30 - removed.insert(name.clone(), package.clone()); 31 } 32 - DiffType::Changed => { 33 - changed.insert(name.clone(), package.clone()); 34 - } 35 - _ => {} 36 } 37 38 - size_delta += package.size_delta; 39 - longest_name = longest_name.max(name.len()); 40 - } 41 - 42 - PackageListDiff { 43 - added, 44 - removed, 45 - changed, 46 - size_delta, 47 - longest_name, 48 } 49 } 50
··· 14 longest_name: usize, 15 } 16 17 + impl From<DiffRoot> for PackageListDiff { 18 + fn from(diff: DiffRoot) -> Self { 19 + let mut out = PackageListDiff { 20 + added: BTreeMap::new(), 21 + removed: BTreeMap::new(), 22 + changed: BTreeMap::new(), 23 + size_delta: 0, 24 + longest_name: 0, 25 + }; 26 27 + for (name, package) in diff.packages { 28 + out.size_delta += package.size_delta; 29 + out.longest_name = out.longest_name.max(name.len()); 30 + 31 + match package.diff_type { 32 + DiffType::Added => { 33 + out.added.insert(name, package); 34 + } 35 + DiffType::Removed => { 36 + out.removed.insert(name, package); 37 + } 38 + DiffType::Changed => { 39 + out.changed.insert(name, package); 40 + } 41 + DiffType::Unknown => { 42 + // This should never happen, but just in case 43 + eprintln!("Unknown diff type for package: {name}"); 44 + } 45 } 46 } 47 48 + out 49 } 50 } 51
+2 -2
src/main.rs
··· 2 3 use argh::FromArgs; 4 use color_eyre::Result; 5 use nu_ansi_term::{Color, Style}; 6 7 mod diff; ··· 44 std::process::exit(1); 45 } 46 47 - let diff = parser::diff(&before, &after)?; 48 - let packages = diff::partition_diff(&diff); 49 50 let arrow_style = Style::new().bold().fg(Color::LightGray); 51
··· 2 3 use argh::FromArgs; 4 use color_eyre::Result; 5 + use diff::PackageListDiff; 6 use nu_ansi_term::{Color, Style}; 7 8 mod diff; ··· 45 std::process::exit(1); 46 } 47 48 + let packages: PackageListDiff = parser::diff(&before, &after)?.into(); 49 50 let arrow_style = Style::new().bold().fg(Color::LightGray); 51
+6 -4
src/package.rs
··· 1 use nu_ansi_term::Color::{Green, Red}; 2 use serde::de::Deserializer; 3 use serde::Deserialize; 4 5 - #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] 6 pub enum DiffType { 7 Added, 8 Removed, ··· 12 Unknown, 13 } 14 15 - #[derive(Deserialize, Clone, Debug)] 16 #[serde(rename_all = "camelCase")] 17 pub struct Package { 18 pub size_delta: i64, ··· 32 where 33 D: Deserializer<'de>, 34 { 35 - let vec = Vec::<String>::deserialize(deserializer)?; 36 Ok(vec 37 .into_iter() 38 .map(|s| { 39 if s.is_empty() { 40 "<none>".to_string() 41 } else { 42 - s 43 } 44 }) 45 .collect())
··· 1 + use std::borrow::Cow; 2 + 3 use nu_ansi_term::Color::{Green, Red}; 4 use serde::de::Deserializer; 5 use serde::Deserialize; 6 7 + #[derive(Default, Debug, PartialEq, Eq)] 8 pub enum DiffType { 9 Added, 10 Removed, ··· 14 Unknown, 15 } 16 17 + #[derive(Deserialize, Debug)] 18 #[serde(rename_all = "camelCase")] 19 pub struct Package { 20 pub size_delta: i64, ··· 34 where 35 D: Deserializer<'de>, 36 { 37 + let vec = Vec::<Cow<'de, str>>::deserialize(deserializer)?; 38 Ok(vec 39 .into_iter() 40 .map(|s| { 41 if s.is_empty() { 42 "<none>".to_string() 43 } else { 44 + s.into_owned() 45 } 46 }) 47 .collect())
+35 -18
src/parser.rs
··· 4 5 use crate::package::{DiffType, Package}; 6 7 - #[derive(Deserialize, Debug)] 8 pub struct DiffRoot { 9 pub packages: BTreeMap<String, Package>, 10 ··· 12 pub schema: String, 13 } 14 15 fn run_diff(before: &str, after: &str) -> String { 16 let raw_diff = Command::new("nix") 17 .args(["store", "diff-closures", "--json", before, after]) 18 .output() 19 - .expect("Failed to execute command"); 20 21 if !raw_diff.status.success() { 22 - eprintln!("Error: {}", String::from_utf8_lossy(&raw_diff.stderr)); 23 std::process::exit(1); 24 } 25 26 - let diff_output = String::from_utf8_lossy(&raw_diff.stdout); 27 - if diff_output.is_empty() { 28 eprintln!("No differences found."); 29 std::process::exit(0); 30 } 31 32 - diff_output.into_owned() 33 } 34 35 fn parse_diff(input: &str) -> Result<DiffRoot> { 36 - serde_json::from_str(input) 37 - .map(|mut diff_root: DiffRoot| { 38 - for package in diff_root.packages.values_mut() { 39 - package.diff_type = 40 - DiffType::from_versions(&package.versions_before, &package.versions_after); 41 - } 42 - diff_root 43 - }) 44 - .map_err(|e| { 45 - eprintln!("Failed to parse JSON: {e}"); 46 - std::process::exit(1); 47 - }) 48 } 49 50 pub fn diff(before: &str, after: &str) -> Result<DiffRoot> {
··· 4 5 use crate::package::{DiffType, Package}; 6 7 + #[derive(Debug)] 8 pub struct DiffRoot { 9 pub packages: BTreeMap<String, Package>, 10 ··· 12 pub schema: String, 13 } 14 15 + impl<'de> Deserialize<'de> for DiffRoot { 16 + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 17 + where 18 + D: serde::Deserializer<'de>, 19 + { 20 + #[derive(Deserialize)] 21 + struct Raw { 22 + packages: BTreeMap<String, Package>, 23 + schema: String, 24 + } 25 + 26 + let Raw { 27 + mut packages, 28 + schema, 29 + } = Raw::deserialize(deserializer)?; 30 + 31 + for pkg in packages.values_mut() { 32 + pkg.diff_type = DiffType::from_versions(&pkg.versions_before, &pkg.versions_after); 33 + } 34 + 35 + Ok(DiffRoot { packages, schema }) 36 + } 37 + } 38 + 39 fn run_diff(before: &str, after: &str) -> String { 40 let raw_diff = Command::new("nix") 41 .args(["store", "diff-closures", "--json", before, after]) 42 .output() 43 + .expect("Failed to execute nix command"); 44 45 if !raw_diff.status.success() { 46 + eprintln!("{}", String::from_utf8_lossy(&raw_diff.stderr)); 47 std::process::exit(1); 48 } 49 50 + let stdout = raw_diff.stdout; 51 + if stdout.is_empty() { 52 eprintln!("No differences found."); 53 std::process::exit(0); 54 } 55 56 + // Assume nix output is valid UTF-8 57 + String::from_utf8(stdout).expect("Output was not valid UTF-8") 58 } 59 60 fn parse_diff(input: &str) -> Result<DiffRoot> { 61 + serde_json::from_str::<DiffRoot>(input).map_err(|e| { 62 + eprintln!("Failed to parse JSON: {e}"); 63 + std::process::exit(1); 64 + }) 65 } 66 67 pub fn diff(before: &str, after: &str) -> Result<DiffRoot> {