summaryrefslogtreecommitdiffstats
path: root/crates/rebel-parse/src/grammar/task_ref.rs
blob: 77d6c5f90d9345e4496f4374ec9ed1d67a897e8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
pub use rules::*;

use rebel_common::types::TaskIDRef;

#[derive(Debug, Clone, Copy)]
pub struct TaskRef<'a> {
	pub id: TaskIDRef<'a>,
	pub args: TaskArgs<'a>,
}

#[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 TaskFlags {
	pub force_run: bool,
}

peg::parser! {
	pub grammar rules() for str {
		pub rule task_ref_with_flags() -> (TaskRef<'input>, TaskFlags)
			= task:task_ref() flags:task_flags() { (task, flags) }

		pub rule task_ref() -> TaskRef<'input>
			= id:task_id() args:task_args() {
				TaskRef {
					id,
					args,
				}
			}

		rule recipe_id() -> &'input str
			= $(name() ("/" name())?)

		rule task_id() -> TaskIDRef<'input>
			= recipe:recipe_id() "::" task:name() {
				TaskIDRef { recipe, task }
			}

		rule task_args() -> TaskArgs<'input>
			= "@" host:name()? target:tagged(<":">, <name()>)? {
				TaskArgs {
					host,
					target,
				}
			}
			/ { Default::default() }

		rule task_flags() -> TaskFlags
			= force_run:force_run() { TaskFlags { force_run } }

		rule force_run() -> bool
			= "+" { true }
			/ { false }

		rule name() -> &'input str
			= $(['a'..='z' | 'A' ..='Z' | '0'..='9' | '_' | '-']+)

		rule tagged<T>(tag: rule<()>, value: rule<T>) -> T
			= tag() v:value() { v }
	}
}