wdl_doc/command_section.rs
1//! A module containing an extension trait for the [`CommandSection`] AST type.
2
3use wdl_ast::AstNode;
4use wdl_ast::v1::CommandPart;
5use wdl_ast::v1::CommandSection;
6use wdl_ast::v1::StrippedCommandPart;
7
8/// An extension trait for the [`CommandSection`] type that provides
9/// functionality for rendering the command section as a script string.
10pub trait CommandSectionExt {
11 /// Returns the command section as a script string.
12 ///
13 /// This is a concatenation of all text parts and placeholders with common
14 /// whitespace stripped (including whitespace common to the placeholders,
15 /// which is typically ignored as semantically meaningless).
16 fn script(&self) -> String;
17}
18
19impl CommandSectionExt for CommandSection {
20 fn script(&self) -> String {
21 let common_whitespace = self.count_whitespace();
22 match self.strip_whitespace() {
23 Some(v) => v
24 .into_iter()
25 .map(|s| match s {
26 StrippedCommandPart::Text(text) => text,
27 StrippedCommandPart::Placeholder(placeholder) => {
28 let common_whitespace =
29 common_whitespace.expect("common whitespace should be present");
30 let placeholder = placeholder.text().to_string();
31 placeholder
32 .lines()
33 .map(|line| {
34 if line.starts_with(&" ".repeat(common_whitespace))
35 || line.starts_with(&"\t".repeat(common_whitespace))
36 {
37 &line[common_whitespace..]
38 } else {
39 line
40 }
41 })
42 .collect::<Vec<_>>()
43 .join("\n")
44 }
45 })
46 .collect(),
47 None => self
48 .parts()
49 .map(|p| match p {
50 CommandPart::Text(text) => {
51 let mut buffer = String::new();
52 text.unescape_to(self.is_heredoc(), &mut buffer);
53 buffer
54 }
55 CommandPart::Placeholder(placeholder) => placeholder.text().to_string(),
56 })
57 .collect(),
58 }
59 }
60}