use serde::Serialize;
use strum::Display;
use mago_span::HasSpan;
use mago_span::Span;
use crate::ast::ast::expression::Expression;
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
#[serde(tag = "type", content = "value")]
pub enum Variable<'arena> {
Direct(DirectVariable<'arena>),
Indirect(IndirectVariable<'arena>),
Nested(NestedVariable<'arena>),
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
pub struct DirectVariable<'arena> {
pub span: Span,
pub name: &'arena [u8],
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
pub struct IndirectVariable<'arena> {
pub dollar_left_brace: Span,
pub expression: &'arena Expression<'arena>,
pub right_brace: Span,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
pub struct NestedVariable<'arena> {
pub dollar: Span,
pub variable: &'arena Variable<'arena>,
}
impl HasSpan for Variable<'_> {
fn span(&self) -> Span {
match self {
Variable::Direct(node) => node.span(),
Variable::Indirect(node) => node.span(),
Variable::Nested(node) => node.span(),
}
}
}
impl HasSpan for DirectVariable<'_> {
fn span(&self) -> Span {
self.span
}
}
impl HasSpan for IndirectVariable<'_> {
fn span(&self) -> Span {
Span::between(self.dollar_left_brace, self.right_brace)
}
}
impl HasSpan for NestedVariable<'_> {
fn span(&self) -> Span {
Span::between(self.dollar, self.variable.span())
}
}