summaryrefslogtreecommitdiff
path: root/src/repo/profile/make_defaults/parsers.rs
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2025-11-29 20:43:28 +0000
committerJohn Turner <jturner.usa@gmail.com>2025-11-29 20:50:59 +0000
commitd1127df296aa7871555293e324d125e6d8a843e1 (patch)
treebaddfab365df586207fa9c1dadf270ee94c3f46f /src/repo/profile/make_defaults/parsers.rs
parent94f3397d197e47eb58a7391acd9c63c5565fa26e (diff)
downloadgentoo-utils-profiles.tar.gz
impl profile evaluationprofiles
Diffstat (limited to 'src/repo/profile/make_defaults/parsers.rs')
-rw-r--r--src/repo/profile/make_defaults/parsers.rs88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/repo/profile/make_defaults/parsers.rs b/src/repo/profile/make_defaults/parsers.rs
new file mode 100644
index 0000000..4d27791
--- /dev/null
+++ b/src/repo/profile/make_defaults/parsers.rs
@@ -0,0 +1,88 @@
+use mon::{Parser, ParserIter, ascii_alpha, ascii_alphanumeric, r#if, one_of, tag};
+
+use crate::{
+ Parseable,
+ repo::profile::make_defaults::{Assignment, Interpolation, Key, Literal, Segment},
+};
+
+impl<'a> Parseable<'a, &'a str> for Key {
+ type Parser = impl Parser<&'a str, Output = Self>;
+
+ fn parser() -> Self::Parser {
+ let start = ascii_alpha();
+ let rest = ascii_alphanumeric()
+ .or(one_of("_".chars()))
+ .repeated()
+ .many();
+
+ start
+ .followed_by(rest)
+ .recognize()
+ .map(|output: &str| Key(output.to_string()))
+ }
+}
+
+impl<'a> Parseable<'a, &'a str> for Literal {
+ type Parser = impl Parser<&'a str, Output = Self>;
+
+ fn parser() -> Self::Parser {
+ r#if(|c: &char| *c != '"')
+ .and_not(Interpolation::parser())
+ .repeated()
+ .at_least(1)
+ .recognize()
+ .map(|output: &str| Literal(output.to_string()))
+ }
+}
+
+impl<'a> Parseable<'a, &'a str> for Interpolation {
+ type Parser = impl Parser<&'a str, Output = Self>;
+
+ fn parser() -> Self::Parser {
+ Key::parser()
+ .recognize()
+ .delimited_by(tag("{"), tag("}"))
+ .preceded_by(tag("$"))
+ .map(|output: &str| Interpolation(output.to_string()))
+ }
+}
+
+impl<'a> Parseable<'a, &'a str> for Segment {
+ type Parser = impl Parser<&'a str, Output = Self>;
+
+ fn parser() -> Self::Parser {
+ Literal::parser()
+ .map(Segment::Literal)
+ .or(Interpolation::parser().map(Segment::Interpolation))
+ }
+}
+
+impl<'a> Parseable<'a, &'a str> for Assignment {
+ type Parser = impl Parser<&'a str, Output = Self>;
+
+ fn parser() -> Self::Parser {
+ Key::parser()
+ .followed_by(tag("="))
+ .and(
+ Segment::parser()
+ .repeated()
+ .many()
+ .delimited_by(tag("\""), tag("\"")),
+ )
+ .map(|(key, value)| Assignment(key, value))
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use mon::input::InputIter;
+
+ use super::*;
+
+ #[test]
+ fn test_parse_value() {
+ let it = InputIter::new(r#"KEY="foo ${bar}""#);
+
+ Assignment::parser().check_finished(it).unwrap();
+ }
+}