#[derive(Debug, Clone, Copy)] pub struct TaskID<'a> { pub recipe: &'a str, pub task: &'a str, } #[derive(Debug, Clone, Copy, Default)] pub struct TaskArgs<'a> { pub host: Option<&'a str>, pub target: Option<&'a str>, } #[derive(Debug, Clone, Copy)] pub struct Task<'a> { pub id: TaskID<'a>, pub args: TaskArgs<'a>, } #[derive(Debug, Clone, Copy)] pub struct TaskFlags { pub force_run: bool, } peg::parser! { grammar rules() for str { rule t(tag: rule<()>, value: rule) -> T = tag() v:value() { v } rule name_char() = ['a'..='z' | 'A' ..='Z' | '0'..='9' | '_' | '-'] rule name() -> &'input str = $(name_char()+) rule recipe_id() -> &'input str = $(name() ("/" name())?) rule task_id() -> TaskID<'input> = recipe:recipe_id() ":" task:name() { TaskID { recipe, task } } rule task_args() -> TaskArgs<'input> = "@" host:name()? target:t(<":">, )? { TaskArgs { host, target, } } / { Default::default() } pub rule task() -> Task<'input> = id:task_id() args:task_args() { Task { id, args, } } rule force_run() -> bool = "+" { true } / { false } rule task_flags() -> TaskFlags = force_run:force_run() { TaskFlags { force_run } } pub rule task_with_flags() -> (Task<'input>, TaskFlags) = task:task() flags:task_flags() { (task, flags) } } } pub use rules::*;