fix reading group sections

This commit is contained in:
steven-omaha
2023-01-10 14:13:36 +01:00
parent 832b94e2dc
commit 7bf464b732
6 changed files with 47 additions and 44 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ pub(crate) trait Backend {
.skip(1) .skip(1)
.filter(|line| !line.starts_with('[')) .filter(|line| !line.starts_with('['))
.fuse() .fuse()
.map(Package::from) .filter_map(Package::try_from)
.collect() .collect()
} }
+1 -1
View File
@@ -47,7 +47,7 @@ fn get_explicitly_installed_packages_from_alpm() -> HashSet<String> {
} }
fn convert_to_pacdef_packages(packages: HashSet<String>) -> HashSet<Package> { fn convert_to_pacdef_packages(packages: HashSet<String>) -> HashSet<Package> {
packages.into_iter().map(Package::from).collect() packages.into_iter().filter_map(Package::try_from).collect()
} }
impl Pacman { impl Pacman {
+1 -1
View File
@@ -17,7 +17,7 @@ impl Backend for Rust {
fn get_all_installed_packages(&self) -> HashSet<Package> { fn get_all_installed_packages(&self) -> HashSet<Package> {
extract_packages_names(&run_cargo_install_list()) extract_packages_names(&run_cargo_install_list())
.map(Package::from) .filter_map(Package::try_from)
.collect() .collect()
} }
+14 -14
View File
@@ -1,13 +1,11 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::fs::{read_to_string, File}; use std::fs::read_to_string;
use std::hash::Hash; use std::hash::Hash;
use std::io::{BufRead, BufReader};
use std::path::Path; use std::path::Path;
use anyhow::{anyhow, Context, Result}; use anyhow::{Context, Result};
use crate::section::Section; use crate::section::Section;
use crate::Package;
#[derive(Debug)] #[derive(Debug)]
pub struct Group { pub struct Group {
@@ -21,10 +19,11 @@ impl Group {
let path = crate::path::get_pacdef_group_dir().context("getting pacdef group dir")?; let path = crate::path::get_pacdef_group_dir().context("getting pacdef group dir")?;
for entry in path.read_dir().context("reading 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 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); result.insert(group);
} }
@@ -63,11 +62,11 @@ impl Eq for Group {
fn assert_receiver_is_total_eq(&self) {} fn assert_receiver_is_total_eq(&self) {}
} }
impl<P> From<P> for Group impl Group {
where fn try_from<P>(p: P) -> Result<Self>
P: AsRef<Path>, where
{ P: AsRef<Path>,
fn from(p: P) -> Self { {
let path = p.as_ref(); let path = p.as_ref();
let content = read_to_string(path).unwrap(); let content = read_to_string(path).unwrap();
let name = path.file_name().unwrap().to_string_lossy().to_string(); let name = path.file_name().unwrap().to_string_lossy().to_string();
@@ -76,10 +75,11 @@ where
let mut sections = HashSet::new(); let mut sections = HashSet::new();
while lines.peek().is_some() { while lines.peek().is_some() {
let section = Section::from_lines(&mut lines); if let Ok(section) = Section::try_from_lines(&mut lines).context("reading section") {
sections.insert(section); sections.insert(section);
}
} }
Self { name, sections } Ok(Self { name, sections })
} }
} }
+15 -17
View File
@@ -8,21 +8,6 @@ pub struct Package {
repo: Option<String>, repo: Option<String>,
} }
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<String> for Package {
fn from(value: String) -> Self {
Package::from(value.as_ref())
}
}
fn remove_all_but_package_name(s: &str) -> &str { fn remove_all_but_package_name(s: &str) -> &str {
s.split('#') // remove comment s.split('#') // remove comment
.next() .next()
@@ -36,7 +21,7 @@ impl Package {
) -> HashSet<Self> { ) -> HashSet<Self> {
lines lines
.into_iter() .into_iter()
.map(|l| Package::from(l.unwrap())) .filter_map(|l| Package::try_from(l.unwrap()))
.collect() .collect()
} }
@@ -46,6 +31,19 @@ impl Package {
let repo = iter.next().map(|s| s.to_string()); let repo = iter.next().map(|s| s.to_string());
(name, repo) (name, repo)
} }
pub(crate) fn try_from<S>(s: S) -> Option<Self>
where
S: AsRef<str>,
{
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 { impl PartialEq for Package {
@@ -100,7 +98,7 @@ mod tests {
#[test] #[test]
fn from() { fn from() {
let x = "myrepo/somepackage # ".to_string(); 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.name, "somepackage");
assert_eq!(p.repo, Some("myrepo".to_string())); assert_eq!(p.repo, Some("myrepo".to_string()));
} }
+15 -10
View File
@@ -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; use crate::Package;
@@ -13,22 +15,25 @@ impl Section {
Self { name, packages } Self { name, packages }
} }
pub fn from_lines<'a>(iter: &mut (impl Iterator<Item = &'a str> + std::fmt::Debug)) -> Self { pub(crate) fn try_from_lines<'a>(
iter: &mut Peekable<(impl Iterator<Item = &'a str> + std::fmt::Debug)>,
) -> Result<Self> {
let name = iter let name = iter
.find(|line| line.starts_with('[')) .find(|line| line.starts_with('['))
.unwrap() .context("finding beginning of next section")?
.trim() .trim()
.trim_start_matches('[') .trim_start_matches('[')
.trim_end_matches(']') .trim_end_matches(']')
.to_string(); .to_string();
let packages = iter let mut packages = HashSet::new();
.take_while(|line| !line.starts_with('[')) // `while let` is unstable, unfortunately
.map(Package::try_from) while iter.peek().is_some() && !iter.peek().unwrap().starts_with('[') {
.filter_map(|p| p.ok()) if let Some(package) = Package::try_from(iter.next().unwrap()) {
.collect(); packages.insert(package);
}
Self::new(name, packages) }
Ok(Self::new(name, packages))
} }
} }