1use smol_str::SmolStr;
2use text_size::TextRange;
3
4use crate::{GuardKind, ShellKind, ShellSelection};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct DocumentAst {
8 pub directives: Vec<DirectiveAst>,
9 pub namespaces: Vec<NamespaceAst>,
10 pub tasks: Vec<TaskAst>,
11 pub uses_braced_namespaces: bool,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum DirectiveAst {
16 Version {
17 major: u64,
18 minor: u64,
19 range: TextRange,
20 },
21 Shell {
22 shell: ShellKind,
23 range: TextRange,
24 },
25 Variable {
26 name: SmolStr,
27 value: SmolStr,
28 name_range: TextRange,
29 range: TextRange,
30 },
31}
32
33#[derive(Debug, Clone, PartialEq, Eq)]
34pub struct NamespaceAst {
35 pub name: SmolStr,
36 pub doc: Option<SmolStr>,
37 pub metadata: TaskMetadataAst,
38 pub range: TextRange,
39 pub close_range: Option<TextRange>,
40 pub is_braced: bool,
41 pub is_group: bool,
42}
43
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct TaskAst {
46 pub name: SmolStr,
47 pub namespace: Option<SmolStr>,
48 pub doc: Option<SmolStr>,
50 pub metadata: TaskMetadataAst,
51 pub params: Vec<ParamAst>,
52 pub guards: Vec<GuardAst>,
53 pub dependencies: Vec<DependencyAst>,
54 pub shell: Option<ShellAst>,
55 pub steps: Vec<TaskStepAst>,
56 pub range: TextRange,
57 pub uses_multiline_header: bool,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, Default)]
61pub struct TaskMetadataAst {
62 pub help: Option<SmolStr>,
63 pub help_count: usize,
64 pub desc: Option<SmolStr>,
65 pub pass: Option<SmolStr>,
66 pub fail: Option<SmolStr>,
67 pub unknown_fields: Vec<SmolStr>,
68 pub has_structured_fields: bool,
69}
70
71impl TaskAst {
72 pub fn qualified_name(&self) -> SmolStr {
73 match &self.namespace {
74 Some(namespace) => SmolStr::from(format!("{namespace}.{}", self.name)),
75 None => self.name.clone(),
76 }
77 }
78
79 pub fn signature(&self) -> SmolStr {
80 let mut signature = self.name.to_string();
81 signature.push('(');
82 signature.push_str(
83 &self
84 .params
85 .iter()
86 .map(
87 |parameter| match (parameter.is_slice, ¶meter.default_value) {
88 (true, Some(default)) => format!("{}..=\"{default}\"", parameter.name),
89 (true, None) => format!("{}..", parameter.name),
90 (false, Some(default)) => format!("{}=\"{default}\"", parameter.name),
91 (false, None) => parameter.name.to_string(),
92 },
93 )
94 .collect::<Vec<_>>()
95 .join(", "),
96 );
97 signature.push(')');
98 SmolStr::from(signature)
99 }
100
101 pub fn is_helper(&self) -> bool {
109 self.name.starts_with('_')
110 }
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct ParamAst {
115 pub name: SmolStr,
116 pub default_value: Option<SmolStr>,
117 pub is_slice: bool,
118 pub range: TextRange,
119}
120
121#[derive(Debug, Clone, PartialEq, Eq)]
122pub struct GuardAst {
123 pub kind: GuardKind,
124 pub argument: SmolStr,
125 pub range: TextRange,
126}
127
128#[derive(Debug, Clone, PartialEq, Eq)]
129pub struct ShellAst {
130 pub selection: ShellSelection,
131 pub range: TextRange,
132}
133
134#[derive(Debug, Clone, PartialEq, Eq)]
135pub struct DependencyAst {
136 pub name: SmolStr,
137 pub range: TextRange,
138 pub arguments: Vec<DependencyArgumentAst>,
139 pub invocation_range: TextRange,
140 pub stage: usize,
141}
142
143#[derive(Debug, Clone, PartialEq, Eq)]
144pub struct DependencyArgumentAst {
145 pub value: SmolStr,
146 pub range: TextRange,
147}
148
149#[derive(Debug, Clone, PartialEq, Eq)]
150pub struct CommandAst {
151 pub text: SmolStr,
152 pub interpolations: Vec<InterpolationAst>,
153 pub range: TextRange,
154}
155
156#[derive(Debug, Clone, PartialEq, Eq)]
157pub enum TaskStepAst {
158 Command(CommandAst),
159 CommandBlock(CommandBlockAst),
160}
161
162impl TaskStepAst {
163 pub fn source(&self) -> &str {
164 match self {
165 Self::Command(command) => command.text.as_str(),
166 Self::CommandBlock(block) => block.source.as_str(),
167 }
168 }
169
170 pub fn interpolations(&self) -> &[InterpolationAst] {
171 match self {
172 Self::Command(command) => &command.interpolations,
173 Self::CommandBlock(block) => &block.interpolations,
174 }
175 }
176}
177
178#[derive(Debug, Clone, PartialEq, Eq)]
179pub struct CommandBlockAst {
180 pub source: SmolStr,
181 pub interpolations: Vec<InterpolationAst>,
182 pub range: TextRange,
183 pub line_ranges: Vec<TextRange>,
184}
185
186#[derive(Debug, Clone, PartialEq, Eq)]
187pub struct InterpolationAst {
188 pub name: SmolStr,
189 pub range: TextRange,
190}