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