mago_syntax/ast/ast/loop/
while.rs1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::ast::expression::Expression;
8use crate::ast::ast::keyword::Keyword;
9use crate::ast::ast::statement::Statement;
10use crate::ast::ast::terminator::Terminator;
11use crate::ast::sequence::Sequence;
12
13#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
27pub struct While<'arena> {
28 pub r#while: Keyword<'arena>,
29 pub left_parenthesis: Span,
30 pub condition: &'arena Expression<'arena>,
31 pub right_parenthesis: Span,
32 pub body: WhileBody<'arena>,
33}
34
35#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
37#[serde(tag = "type", content = "value")]
38pub enum WhileBody<'arena> {
39 Statement(&'arena Statement<'arena>),
40 ColonDelimited(WhileColonDelimitedBody<'arena>),
41}
42
43#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
57pub struct WhileColonDelimitedBody<'arena> {
58 pub colon: Span,
59 pub statements: Sequence<'arena, Statement<'arena>>,
60 pub end_while: Keyword<'arena>,
61 pub terminator: Terminator<'arena>,
62}
63
64impl<'arena> WhileBody<'arena> {
65 #[inline]
66 #[must_use]
67 pub fn statements(&self) -> &[Statement<'arena>] {
68 match self {
69 WhileBody::Statement(statement) => std::slice::from_ref(statement),
70 WhileBody::ColonDelimited(body) => body.statements.as_slice(),
71 }
72 }
73}
74
75impl HasSpan for While<'_> {
76 fn span(&self) -> Span {
77 self.r#while.span().join(self.body.span())
78 }
79}
80
81impl HasSpan for WhileBody<'_> {
82 fn span(&self) -> Span {
83 match self {
84 WhileBody::Statement(statement) => statement.span(),
85 WhileBody::ColonDelimited(body) => body.span(),
86 }
87 }
88}
89
90impl HasSpan for WhileColonDelimitedBody<'_> {
91 fn span(&self) -> Span {
92 self.colon.join(self.terminator.span())
93 }
94}