wdl_ast/v1/task/runtime/item/
container.rs1use wdl_grammar::SyntaxKind;
4use wdl_grammar::SyntaxNode;
5
6use crate::AstNode;
7use crate::AstToken;
8use crate::TreeNode;
9use crate::v1::RuntimeItem;
10use crate::v1::TASK_REQUIREMENT_CONTAINER;
11use crate::v1::TASK_REQUIREMENT_CONTAINER_ALIAS;
12use crate::v1::common::container::value;
13use crate::v1::common::container::value::Value;
14
15#[derive(Debug)]
17pub struct Container<N: TreeNode = SyntaxNode>(RuntimeItem<N>);
18
19impl<N: TreeNode> Container<N> {
20 pub fn value(&self) -> value::Result<Value<N>> {
22 Value::try_from(self.0.expr())
23 }
24}
25
26impl<N: TreeNode> AstNode<N> for Container<N> {
27 fn can_cast(kind: SyntaxKind) -> bool {
28 RuntimeItem::<N>::can_cast(kind)
29 }
30
31 fn cast(inner: N) -> Option<Self> {
32 RuntimeItem::cast(inner).and_then(|item| Container::try_from(item).ok())
33 }
34
35 fn inner(&self) -> &N {
36 self.0.inner()
37 }
38}
39
40impl<N: TreeNode> TryFrom<RuntimeItem<N>> for Container<N> {
41 type Error = ();
42
43 fn try_from(value: RuntimeItem<N>) -> Result<Self, Self::Error> {
44 if [TASK_REQUIREMENT_CONTAINER, TASK_REQUIREMENT_CONTAINER_ALIAS]
45 .iter()
46 .any(|key| value.name().text() == *key)
47 {
48 return Ok(Self(value));
49 }
50
51 Err(())
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::Document;
58
59 #[test]
60 fn simple_example() {
61 let (document, diagnostics) = Document::parse(
62 r#"version 1.2
63
64task hello {
65 runtime {
66 container: "ubuntu"
67 }
68}"#,
69 );
70
71 assert!(diagnostics.is_empty());
72
73 let section = document
74 .ast()
75 .as_v1()
76 .expect("v1 ast")
77 .tasks()
78 .next()
79 .expect("the 'hello' task to exist")
80 .runtime()
81 .expect("the 'runtime' block to exist");
82
83 let container = section.items().filter_map(|p| p.into_container());
84
85 assert!(container.count() == 1);
86 }
87
88 #[test]
89 fn missing_container_item() {
90 let (document, diagnostics) = Document::parse(
91 r#"version 1.2
92
93task hello {
94 runtime {
95 foo: "ubuntu"
96 }
97}"#,
98 );
99
100 assert!(diagnostics.is_empty());
101
102 let section = document
103 .ast()
104 .as_v1()
105 .expect("v1 ast")
106 .tasks()
107 .next()
108 .expect("the 'hello' task to exist")
109 .runtime()
110 .expect("the 'runtime' block to exist");
111
112 let container = section.items().filter_map(|p| p.into_container());
113
114 assert!(container.count() == 0);
115 }
116
117 #[test]
118 fn docker_alias() {
119 let (document, diagnostics) = Document::parse(
120 r#"version 1.2
121
122task hello {
123 runtime {
124 docker: "ubuntu"
125 }
126}"#,
127 );
128
129 assert!(diagnostics.is_empty());
130
131 let section = document
132 .ast()
133 .as_v1()
134 .expect("v1 ast")
135 .tasks()
136 .next()
137 .expect("the 'hello' task to exist")
138 .runtime()
139 .expect("the 'runtime' block to exist");
140
141 let container = section.items().filter_map(|p| p.into_container());
142
143 assert!(container.count() == 1);
144 }
145}