forked from gentoo-utils/gentoo-utils
89 lines
2.2 KiB
Rust
89 lines
2.2 KiB
Rust
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();
|
|
}
|
|
}
|