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