forked from gentoo-utils/gentoo-utils
impl profile evaluation
This commit is contained in:
88
src/repo/profile/make_defaults/parsers.rs
Normal file
88
src/repo/profile/make_defaults/parsers.rs
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user