Skip to main content

only_semantic/
ast.rs

1use smol_str::SmolStr;
2use text_size::TextRange;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct DocumentAst {
6    pub directives: Vec<DirectiveAst>,
7    pub namespaces: Vec<NamespaceAst>,
8    pub tasks: Vec<TaskAst>,
9}
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum DirectiveAst {
13    Shell { shell: SmolStr, range: TextRange },
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct NamespaceAst {
18    pub name: SmolStr,
19    pub doc: Option<SmolStr>,
20    pub range: TextRange,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct TaskAst {
25    pub name: SmolStr,
26    pub namespace: Option<SmolStr>,
27    pub doc: Option<SmolStr>,
28    pub params: Vec<ParamAst>,
29    pub guard: Option<GuardAst>,
30    pub dependencies: Vec<DependencyAst>,
31    pub shell: Option<SmolStr>,
32    pub shell_fallback: bool,
33    pub commands: Vec<CommandAst>,
34    pub range: TextRange,
35}
36
37impl TaskAst {
38    pub fn qualified_name(&self) -> SmolStr {
39        match &self.namespace {
40            Some(namespace) => SmolStr::from(format!("{namespace}.{}", self.name)),
41            None => self.name.clone(),
42        }
43    }
44
45    pub fn signature(&self) -> SmolStr {
46        let mut signature = self.name.to_string();
47        signature.push('(');
48        signature.push_str(
49            &self
50                .params
51                .iter()
52                .map(|parameter| match &parameter.default_value {
53                    Some(default) => format!("{}=\"{default}\"", parameter.name),
54                    None => parameter.name.to_string(),
55                })
56                .collect::<Vec<_>>()
57                .join(", "),
58        );
59        signature.push(')');
60        SmolStr::from(signature)
61    }
62
63    /// Returns whether the task is a helper task hidden from normal CLI listings.
64    ///
65    /// Args:
66    /// None.
67    ///
68    /// Returns:
69    /// `true` when the task name starts with `_`.
70    pub fn is_helper(&self) -> bool {
71        self.name.starts_with('_')
72    }
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
76pub struct ParamAst {
77    pub name: SmolStr,
78    pub default_value: Option<SmolStr>,
79}
80
81#[derive(Debug, Clone, PartialEq, Eq)]
82pub struct GuardAst {
83    pub kind: SmolStr,
84    pub argument: SmolStr,
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct DependencyAst {
89    pub name: SmolStr,
90    pub range: TextRange,
91    pub stage: usize,
92}
93
94#[derive(Debug, Clone, PartialEq, Eq)]
95pub struct CommandAst {
96    pub text: SmolStr,
97    pub interpolations: Vec<InterpolationAst>,
98}
99
100#[derive(Debug, Clone, PartialEq, Eq)]
101pub struct InterpolationAst {
102    pub name: SmolStr,
103    pub range: TextRange,
104}