summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/repo/meson.build2
-rw-r--r--src/repo/mod.rs29
-rw-r--r--src/repo/parsers.rs20
-rw-r--r--tests/profile/mockrepo/profiles/arch.list2
-rw-r--r--tests/profile/read_mock_profile.rs8
5 files changed, 60 insertions, 1 deletions
diff --git a/src/repo/meson.build b/src/repo/meson.build
index d59b73e..e706ad9 100644
--- a/src/repo/meson.build
+++ b/src/repo/meson.build
@@ -1,4 +1,4 @@
-sources += files('mod.rs')
+sources += files('mod.rs', 'parsers.rs')
subdir('ebuild')
subdir('profile')
diff --git a/src/repo/mod.rs b/src/repo/mod.rs
index 5db8a6f..87d0484 100644
--- a/src/repo/mod.rs
+++ b/src/repo/mod.rs
@@ -19,6 +19,7 @@ use crate::{
};
pub mod ebuild;
+mod parsers;
pub mod profile;
#[derive(Debug, thiserror::Error)]
@@ -37,6 +38,9 @@ pub enum Error {
Profile(profile::Error),
}
+#[derive(Debug, Clone, PartialEq, Eq, Get)]
+pub struct Arch(#[get(method = "get", kind = "deref")] String);
+
#[derive(Debug, Clone, Get)]
pub struct Repo {
#[get(kind = "deref")]
@@ -45,6 +49,8 @@ pub struct Repo {
name: String,
#[get(kind = "deref")]
package_mask: Vec<Atom>,
+ #[get(kind = "deref")]
+ arch_list: Vec<Arch>,
}
#[derive(Debug, Clone, Get)]
@@ -80,10 +86,19 @@ impl Repo {
Err(e) => return Err(Error::Io(package_mask_path, e)),
};
+ let arch_list_path = path.as_ref().join("profiles/arch.list");
+ let arch_list = match fs::read_to_string(&arch_list_path).map(|s| read_arch_list(&s)) {
+ Ok(Ok(arch_list)) => arch_list,
+ Ok(Err(e)) => return Err(e),
+ Err(e) if matches!(e.kind(), io::ErrorKind::NotFound) => Vec::new(),
+ Err(e) => return Err(Error::Io(arch_list_path, e)),
+ };
+
Ok(Self {
path: path.as_ref().to_path_buf(),
name,
package_mask,
+ arch_list,
})
}
@@ -366,6 +381,20 @@ fn read_package_mask(input: &str) -> Result<Vec<Atom>, Error> {
.collect())
}
+fn read_arch_list(input: &str) -> Result<Vec<Arch>, Error> {
+ Ok(LineBasedFileExpr::<Arch>::parser()
+ .separated_by_with_opt_trailing(ascii_whitespace1())
+ .many()
+ .parse_finished(InputIter::new(input))
+ .map_err(|it| Error::Parser(it.rest().to_string()))?
+ .into_iter()
+ .filter_map(|expr| match expr {
+ LineBasedFileExpr::Comment => None,
+ LineBasedFileExpr::Expr(arch) => Some(arch),
+ })
+ .collect())
+}
+
fn parse_depends(line: &str) -> Result<Vec<Depend<Atom>>, Error> {
Depend::<Atom>::parser()
.separated_by(ascii_whitespace1())
diff --git a/src/repo/parsers.rs b/src/repo/parsers.rs
new file mode 100644
index 0000000..ccef666
--- /dev/null
+++ b/src/repo/parsers.rs
@@ -0,0 +1,20 @@
+use mon::{Parser, ParserIter, ascii_alphanumeric, one_of};
+
+use crate::{Parseable, repo::Arch};
+
+impl<'a> Parseable<'a, &'a str> for Arch {
+ type Parser = impl Parser<&'a str, Output = Self>;
+
+ fn parser() -> Self::Parser {
+ let start = ascii_alphanumeric();
+ let rest = ascii_alphanumeric()
+ .or(one_of("-".chars()))
+ .repeated()
+ .many();
+
+ start
+ .and(rest)
+ .recognize()
+ .map(|output: &str| Arch(output.to_string()))
+ }
+}
diff --git a/tests/profile/mockrepo/profiles/arch.list b/tests/profile/mockrepo/profiles/arch.list
new file mode 100644
index 0000000..afe9227
--- /dev/null
+++ b/tests/profile/mockrepo/profiles/arch.list
@@ -0,0 +1,2 @@
+amd64
+aarch64 \ No newline at end of file
diff --git a/tests/profile/read_mock_profile.rs b/tests/profile/read_mock_profile.rs
index da50216..440dce2 100644
--- a/tests/profile/read_mock_profile.rs
+++ b/tests/profile/read_mock_profile.rs
@@ -18,6 +18,14 @@ fn main() {
assert_eq!(global_package_mask, vec!["app-editors/vim"]);
+ assert_eq!(
+ repo.arch_list()
+ .iter()
+ .map(|arch| arch.get())
+ .collect::<Vec<_>>(),
+ vec!["amd64", "aarch64"]
+ );
+
let profile = repo
.evaluate_profile("gentoo-desktop")
.expect("failed to evaluate profile");