From 7bf464b7324cbe61122bc985a5edab41aa0ef4f5 Mon Sep 17 00:00:00 2001 From: steven-omaha <35634100+steven-omaha@users.noreply.github.com> Date: Tue, 10 Jan 2023 14:13:36 +0100 Subject: [PATCH] fix reading group sections --- src/backend/mod.rs | 2 +- src/backend/pacman.rs | 2 +- src/backend/rust.rs | 2 +- src/group.rs | 28 ++++++++++++++-------------- src/package.rs | 32 +++++++++++++++----------------- src/section.rs | 25 +++++++++++++++---------- 6 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/backend/mod.rs b/src/backend/mod.rs index de7cbe8..4b75929 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -103,7 +103,7 @@ pub(crate) trait Backend { .skip(1) .filter(|line| !line.starts_with('[')) .fuse() - .map(Package::from) + .filter_map(Package::try_from) .collect() } diff --git a/src/backend/pacman.rs b/src/backend/pacman.rs index 9518c52..43e6067 100644 --- a/src/backend/pacman.rs +++ b/src/backend/pacman.rs @@ -47,7 +47,7 @@ fn get_explicitly_installed_packages_from_alpm() -> HashSet { } fn convert_to_pacdef_packages(packages: HashSet) -> HashSet { - packages.into_iter().map(Package::from).collect() + packages.into_iter().filter_map(Package::try_from).collect() } impl Pacman { diff --git a/src/backend/rust.rs b/src/backend/rust.rs index 288cc7b..82814ef 100644 --- a/src/backend/rust.rs +++ b/src/backend/rust.rs @@ -17,7 +17,7 @@ impl Backend for Rust { fn get_all_installed_packages(&self) -> HashSet { extract_packages_names(&run_cargo_install_list()) - .map(Package::from) + .filter_map(Package::try_from) .collect() } diff --git a/src/group.rs b/src/group.rs index 04b8d09..441f52a 100644 --- a/src/group.rs +++ b/src/group.rs @@ -1,13 +1,11 @@ use std::collections::HashSet; -use std::fs::{read_to_string, File}; +use std::fs::read_to_string; use std::hash::Hash; -use std::io::{BufRead, BufReader}; use std::path::Path; -use anyhow::{anyhow, Context, Result}; +use anyhow::{Context, Result}; use crate::section::Section; -use crate::Package; #[derive(Debug)] pub struct Group { @@ -21,10 +19,11 @@ impl Group { let path = crate::path::get_pacdef_group_dir().context("getting pacdef group dir")?; for entry in path.read_dir().context("reading group dir")? { - let file = entry.context("getting a file")?; + let file = entry.context("getting group file")?; let path = file.path(); - let group = Group::try_from(path)?; + let group = + Group::try_from(&path).with_context(|| format!("reading group file {:?}", path))?; result.insert(group); } @@ -63,11 +62,11 @@ impl Eq for Group { fn assert_receiver_is_total_eq(&self) {} } -impl

From

for Group -where - P: AsRef, -{ - fn from(p: P) -> Self { +impl Group { + fn try_from

(p: P) -> Result + where + P: AsRef, + { let path = p.as_ref(); let content = read_to_string(path).unwrap(); let name = path.file_name().unwrap().to_string_lossy().to_string(); @@ -76,10 +75,11 @@ where let mut sections = HashSet::new(); while lines.peek().is_some() { - let section = Section::from_lines(&mut lines); - sections.insert(section); + if let Ok(section) = Section::try_from_lines(&mut lines).context("reading section") { + sections.insert(section); + } } - Self { name, sections } + Ok(Self { name, sections }) } } diff --git a/src/package.rs b/src/package.rs index b8d1929..b24927d 100644 --- a/src/package.rs +++ b/src/package.rs @@ -8,21 +8,6 @@ pub struct Package { repo: Option, } -impl From<&str> for Package { - fn from(s: &str) -> Self { - let trimmed = remove_all_but_package_name(s); - - let (name, repo) = Self::split_into_name_and_repo(trimmed); - Self { name, repo } - } -} - -impl From for Package { - fn from(value: String) -> Self { - Package::from(value.as_ref()) - } -} - fn remove_all_but_package_name(s: &str) -> &str { s.split('#') // remove comment .next() @@ -36,7 +21,7 @@ impl Package { ) -> HashSet { lines .into_iter() - .map(|l| Package::from(l.unwrap())) + .filter_map(|l| Package::try_from(l.unwrap())) .collect() } @@ -46,6 +31,19 @@ impl Package { let repo = iter.next().map(|s| s.to_string()); (name, repo) } + + pub(crate) fn try_from(s: S) -> Option + where + S: AsRef, + { + let trimmed = remove_all_but_package_name(s.as_ref()); + if trimmed.is_empty() { + return None; + } + + let (name, repo) = Self::split_into_name_and_repo(trimmed); + Some(Self { name, repo }) + } } impl PartialEq for Package { @@ -100,7 +98,7 @@ mod tests { #[test] fn from() { let x = "myrepo/somepackage # ".to_string(); - let p = Package::from(x); + let p = Package::try_from(x).unwrap(); assert_eq!(p.name, "somepackage"); assert_eq!(p.repo, Some("myrepo".to_string())); } diff --git a/src/section.rs b/src/section.rs index d0ef797..f3d6613 100644 --- a/src/section.rs +++ b/src/section.rs @@ -1,4 +1,6 @@ -use std::{collections::HashSet, hash::Hash}; +use std::{collections::HashSet, hash::Hash, iter::Peekable}; + +use anyhow::{Context, Result}; use crate::Package; @@ -13,22 +15,25 @@ impl Section { Self { name, packages } } - pub fn from_lines<'a>(iter: &mut (impl Iterator + std::fmt::Debug)) -> Self { + pub(crate) fn try_from_lines<'a>( + iter: &mut Peekable<(impl Iterator + std::fmt::Debug)>, + ) -> Result { let name = iter .find(|line| line.starts_with('[')) - .unwrap() + .context("finding beginning of next section")? .trim() .trim_start_matches('[') .trim_end_matches(']') .to_string(); - let packages = iter - .take_while(|line| !line.starts_with('[')) - .map(Package::try_from) - .filter_map(|p| p.ok()) - .collect(); - - Self::new(name, packages) + let mut packages = HashSet::new(); + // `while let` is unstable, unfortunately + while iter.peek().is_some() && !iter.peek().unwrap().starts_with('[') { + if let Some(package) = Package::try_from(iter.next().unwrap()) { + packages.insert(package); + } + } + Ok(Self::new(name, packages)) } }