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