this repo has no description

refactor: we are now clone free

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