1use serde::Deserialize;
2use serde::Serialize;
3use strum::Display;
4
5use mago_interner::StringIdentifier;
6use mago_span::HasSpan;
7use mago_span::Span;
8
9use crate::ast::expression::Expression;
10
11#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord, Display)]
21#[serde(tag = "type", content = "value")]
22#[repr(C, u8)]
23pub enum Variable {
24 Direct(DirectVariable),
25 Indirect(IndirectVariable),
26 Nested(NestedVariable),
27}
28
29#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
39#[repr(C)]
40pub struct DirectVariable {
41 pub span: Span,
42 pub name: StringIdentifier,
43}
44
45#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
57#[repr(C)]
58pub struct IndirectVariable {
59 pub dollar_left_brace: Span,
60 pub expression: Box<Expression>,
61 pub right_brace: Span,
62}
63
64#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
76#[repr(C)]
77pub struct NestedVariable {
78 pub dollar: Span,
79 pub variable: Box<Variable>,
80}
81
82impl HasSpan for Variable {
83 fn span(&self) -> Span {
84 match self {
85 Variable::Direct(node) => node.span(),
86 Variable::Indirect(node) => node.span(),
87 Variable::Nested(node) => node.span(),
88 }
89 }
90}
91
92impl HasSpan for DirectVariable {
93 fn span(&self) -> Span {
94 self.span
95 }
96}
97
98impl HasSpan for IndirectVariable {
99 fn span(&self) -> Span {
100 Span::between(self.dollar_left_brace, self.right_brace)
101 }
102}
103
104impl HasSpan for NestedVariable {
105 fn span(&self) -> Span {
106 Span::between(self.dollar, self.variable.span())
107 }
108}