fix reading group sections

This commit is contained in:
Dr. Matthias Ratajczak
2023-01-10 14:13:36 +01:00
parent 91991cf339
commit cdbe0669d3
6 changed files with 47 additions and 44 deletions
+1 -1
View File
@@ -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()
}
+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> {
packages.into_iter().map(Package::from).collect()
packages.into_iter().filter_map(Package::try_from).collect()
}
impl Pacman {
+1 -1
View File
@@ -17,7 +17,7 @@ impl Backend for Rust {
fn get_all_installed_packages(&self) -> HashSet<Package> {
extract_packages_names(&run_cargo_install_list())
.map(Package::from)
.filter_map(Package::try_from)
.collect()
}
+14 -14
View File
@@ -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<P> From<P> for Group
where
P: AsRef<Path>,
{
fn from(p: P) -> Self {
impl Group {
fn try_from<P>(p: P) -> Result<Self>
where
P: AsRef<Path>,
{
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 })
}
}
+15 -17
View File
@@ -8,21 +8,6 @@ pub struct Package {
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 {
s.split('#') // remove comment
.next()
@@ -36,7 +21,7 @@ impl Package {
) -> HashSet<Self> {
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: 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 {
@@ -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()));
}
+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;
@@ -13,22 +15,25 @@ impl Section {
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
.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))
}
}