diff --git a/src/group.rs b/src/group.rs index 3e0d7e2..6e990df 100644 --- a/src/group.rs +++ b/src/group.rs @@ -1,36 +1,33 @@ use std::collections::HashSet; -use std::fs::File; +use std::fs::{read_to_string, File}; use std::hash::Hash; use std::io::{BufRead, BufReader}; +use std::path::Path; use anyhow::{anyhow, Context, Result}; +use crate::section::Section; use crate::Package; #[derive(Debug)] pub struct Group { pub name: String, - pub packages: HashSet, + pub sections: HashSet
, } impl Group { pub fn load_from_dir() -> Result> { let mut result = HashSet::new(); + 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 name = file.file_name(); - let f = File::open(file.path()).context("reading the file")?; - let reader = BufReader::new(f); - let packages = Package::from_lines(reader.lines()); - result.insert(Group { - name: name - .into_string() - .map_err(|e| anyhow!("could not get group name, {e:?}"))?, - packages, - }); + let group = Group::try_from(name)?; + result.insert(group); } + Ok(result) } } @@ -58,10 +55,31 @@ impl Hash for Group { impl PartialEq for Group { fn eq(&self, other: &Self) -> bool { - self.name == other.name && self.packages == other.packages + self.name == other.name } } impl Eq for Group { fn assert_receiver_is_total_eq(&self) {} } + +impl

From

for Group +where + P: AsRef, +{ + fn from(p: P) -> Self { + let path = p.as_ref(); + let content = read_to_string(path).unwrap(); + let name = path.file_name().unwrap().to_string_lossy().to_string(); + + let mut lines = content.lines().peekable(); + let mut sections = HashSet::new(); + + while lines.peek().is_some() { + let section = Section::from_lines(&mut lines); + sections.insert(section); + } + + Self { name, sections } + } +} diff --git a/src/lib.rs b/src/lib.rs index 5da3a48..e37a288 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ mod env; mod group; mod package; mod path; +mod section; mod ui; pub use crate::core::Pacdef; diff --git a/src/section.rs b/src/section.rs new file mode 100644 index 0000000..57cba43 --- /dev/null +++ b/src/section.rs @@ -0,0 +1,38 @@ +use std::{collections::HashSet, hash::Hash}; + +use crate::Package; + +#[derive(Debug, Eq)] +pub struct Section { + pub name: String, + pub packages: HashSet, +} + +impl Section { + pub(crate) fn new(name: String, packages: HashSet) -> Self { + Self { name, packages } + } + + pub fn from_lines<'a>(iter: &mut impl Iterator) -> Self { + let name = iter.find(|line| line.starts_with('[')).unwrap().to_string(); + let packages = iter + .take_while(|line| !line.starts_with('[')) + .filter(|line| !line.contains(char::is_alphabetic)) + .map(Package::from) + .collect(); + + Self::new(name, packages) + } +} + +impl Hash for Section { + fn hash(&self, state: &mut H) { + self.name.hash(state); + } +} + +impl PartialEq for Section { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + } +}