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