mago_syntax/ast/ast/
namespace.rs1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::ast::block::Block;
8use crate::ast::ast::identifier::Identifier;
9use crate::ast::ast::keyword::Keyword;
10use crate::ast::ast::statement::Statement;
11use crate::ast::ast::terminator::Terminator;
12
13use crate::ast::sequence::Sequence;
14
15#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
27pub struct Namespace<'arena> {
28 pub namespace: Keyword<'arena>,
29 pub name: Option<Identifier<'arena>>,
30 pub body: NamespaceBody<'arena>,
31}
32
33#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
35#[serde(tag = "type", content = "value")]
36pub enum NamespaceBody<'arena> {
37 Implicit(NamespaceImplicitBody<'arena>),
38 BraceDelimited(Block<'arena>),
39}
40
41#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
53pub struct NamespaceImplicitBody<'arena> {
54 pub terminator: Terminator<'arena>,
55 pub statements: Sequence<'arena, Statement<'arena>>,
56}
57
58impl<'arena> Namespace<'arena> {
59 #[must_use]
60 pub fn statements(&self) -> &Sequence<'arena, Statement<'arena>> {
61 match &self.body {
62 NamespaceBody::Implicit(body) => &body.statements,
63 NamespaceBody::BraceDelimited(body) => &body.statements,
64 }
65 }
66}
67
68impl HasSpan for Namespace<'_> {
69 fn span(&self) -> Span {
70 self.namespace.span().join(self.body.span())
71 }
72}
73
74impl HasSpan for NamespaceBody<'_> {
75 fn span(&self) -> Span {
76 match self {
77 NamespaceBody::Implicit(body) => body.span(),
78 NamespaceBody::BraceDelimited(body) => body.span(),
79 }
80 }
81}
82
83impl HasSpan for NamespaceImplicitBody<'_> {
84 fn span(&self) -> Span {
85 let terminator_span = self.terminator.span();
86
87 terminator_span.join(self.statements.span(terminator_span.file_id, terminator_span.end))
88 }
89}