diff options
| author | John Turner <jturner.usa@gmail.com> | 2025-10-29 20:06:59 +0000 |
|---|---|---|
| committer | John Turner <jturner.usa@gmail.com> | 2025-10-29 20:06:59 +0000 |
| commit | 72b6774e2b43edf4228df2d5a7af20c041e6745c (patch) | |
| tree | 32ecc67a4349a6d08729062f2127083b8b210b58 /src/ebuild/parsers.rs | |
| parent | 8937e096a4b7eba649817d12d23d3e369a4a4f1d (diff) | |
| download | gentoo-utils-72b6774e2b43edf4228df2d5a7af20c041e6745c.tar.gz | |
impl Repo and md5-cache reading
Diffstat (limited to 'src/ebuild/parsers.rs')
| -rw-r--r-- | src/ebuild/parsers.rs | 71 |
1 files changed, 56 insertions, 15 deletions
diff --git a/src/ebuild/parsers.rs b/src/ebuild/parsers.rs index d079609..ef713d2 100644 --- a/src/ebuild/parsers.rs +++ b/src/ebuild/parsers.rs @@ -4,32 +4,59 @@ use mon::{Parser, alpha1, r#if, tag, whitespace1}; use crate::{ Parseable, - ebuild::{Conditional, Depend, Eapi, License, SrcUri}, + ebuild::{Conditional, Depend, Eapi, Eclass, License, SrcUri, Uri, UriPrefix}, useflag::UseFlag, }; -impl<'a> Parseable<'a, &'a str> for SrcUri { +impl<'a> Parseable<'a, &'a str> for UriPrefix { type Parser = impl Parser<&'a str, Output = Self>; fn parser() -> Self::Parser { - let protocol = alpha1::<&str>().followed_by(tag("://")); + tag("+mirror") + .map(|_| UriPrefix::Mirror) + .or(tag("+fetch").map(|_| UriPrefix::Fetch)) + } +} - let uri = r#if(|c: &char| !c.is_ascii_whitespace()) +impl<'a> Parseable<'a, &'a str> for Uri { + type Parser = impl Parser<&'a str, Output = Self>; + + fn parser() -> Self::Parser { + let protocol = alpha1::<&str>() + .followed_by(tag("://")) + .map(|output: &str| output.to_string()); + let path = r#if(|c: &char| !c.is_ascii_whitespace()) .list(1..) .recognize() .map(|output: &str| output.to_string()); - let name = r#if(|c: &char| !c.is_ascii_whitespace()) - .list(1..) - .recognize() - .map(|output: &str| PathBuf::from(output)); - - uri.preceded_by(protocol) - .and( - name.preceded_by(tag("->").delimited_by(whitespace1(), whitespace1())) - .opt(), - ) - .map(|(uri, file_name)| SrcUri { uri, file_name }) + protocol + .and(path) + .map(|(protocol, path)| Uri { protocol, path }) + } +} + +impl<'a> Parseable<'a, &'a str> for SrcUri { + type Parser = impl Parser<&'a str, Output = Self>; + + fn parser() -> Self::Parser { + let filename = || { + r#if(|c: &char| !c.is_ascii_whitespace()) + .list(1..) + .recognize() + .map(|output: &str| PathBuf::from(output)) + }; + let uri = UriPrefix::parser() + .opt() + .and(Uri::parser()) + .and(filename().preceded_by(tag(" -> ")).opt()) + .map(|((prefix, uri), filename)| SrcUri::Uri { + prefix, + uri, + filename, + }); + + uri.or(filename().map(|path: PathBuf| SrcUri::Filename(path))) } } @@ -61,6 +88,20 @@ impl<'a> Parseable<'a, &'a str> for Eapi { } } +// TODO: +// Cant find information about eclass names in pms so we allow anything except +// for whitespace. +impl<'a> Parseable<'a, &'a str> for Eclass { + type Parser = impl Parser<&'a str, Output = Self>; + + fn parser() -> Self::Parser { + r#if(|c: &char| !c.is_ascii_whitespace()) + .list(1..) + .recognize() + .map(|output: &str| Eclass(output.to_string())) + } +} + impl<'a, T> Parseable<'a, &'a str> for Depend<T> where T: Parseable<'a, &'a str>, |
