mago_ast/ast/loop/
while.rs

1use serde::Deserialize;
2use serde::Serialize;
3use strum::Display;
4
5use mago_span::HasSpan;
6use mago_span::Span;
7
8use crate::ast::expression::Expression;
9use crate::ast::keyword::Keyword;
10use crate::ast::statement::Statement;
11use crate::ast::terminator::Terminator;
12use crate::sequence::Sequence;
13
14/// Represents a while statement in PHP.
15///
16/// Example:
17///
18/// ```php
19/// <?php
20///
21/// $i = 0;
22/// while ($i < 10) {
23///   echo $i;
24///   $i++;
25/// }
26/// ```
27#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
28#[repr(C)]
29pub struct While {
30    pub r#while: Keyword,
31    pub left_parenthesis: Span,
32    pub condition: Box<Expression>,
33    pub right_parenthesis: Span,
34    pub body: WhileBody,
35}
36
37/// Represents the body of a while statement.
38#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord, Display)]
39#[serde(tag = "type", content = "value")]
40#[repr(C, u8)]
41pub enum WhileBody {
42    Statement(Box<Statement>),
43    ColonDelimited(WhileColonDelimitedBody),
44}
45
46/// Represents a colon-delimited body of a while statement.
47///
48/// Example:
49///
50/// ```php
51/// <?php
52///
53/// $i = 0;
54/// while ($i < 10):
55///   echo $i;
56///   $i++;
57/// endwhile;
58/// ```
59#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
60#[repr(C)]
61pub struct WhileColonDelimitedBody {
62    pub colon: Span,
63    pub statements: Sequence<Statement>,
64    pub end_while: Keyword,
65    pub terminator: Terminator,
66}
67
68impl HasSpan for While {
69    fn span(&self) -> Span {
70        self.r#while.span().join(self.body.span())
71    }
72}
73
74impl HasSpan for WhileBody {
75    fn span(&self) -> Span {
76        match self {
77            WhileBody::Statement(statement) => statement.span(),
78            WhileBody::ColonDelimited(body) => body.span(),
79        }
80    }
81}
82
83impl HasSpan for WhileColonDelimitedBody {
84    fn span(&self) -> Span {
85        self.colon.join(self.terminator.span())
86    }
87}