Skip to main content

gobject_ast/model/statement/
switch_stmt.rs

1use serde::Serialize;
2
3use crate::model::{Expression, SourceLocation, Statement};
4
5#[derive(Debug, Clone, Serialize)]
6pub struct CaseLabel {
7    /// The case value expression (e.g., PROP_FOO, 1, N_PROPS + 1)
8    /// None for default case
9    #[serde(skip_serializing_if = "Option::is_none")]
10    pub value: Option<Expression>,
11    pub location: SourceLocation,
12}
13
14#[derive(Debug, Clone, Serialize)]
15pub struct SwitchCase {
16    /// The case label (case PROP_FOO:, default:, etc.)
17    pub label: CaseLabel,
18    /// Statements between this case and the next case/end
19    #[serde(skip_serializing_if = "Vec::is_empty")]
20    pub body: Vec<Statement>,
21}
22
23#[derive(Debug, Clone, Serialize)]
24pub struct SwitchStatement {
25    pub condition: Expression,
26    #[serde(skip)]
27    pub condition_location: SourceLocation,
28    /// Cases with their associated statement bodies
29    #[serde(skip_serializing_if = "Vec::is_empty")]
30    pub cases: Vec<SwitchCase>,
31    pub location: SourceLocation,
32}
33
34impl SwitchStatement {
35    /// Extract identifiers from non-default case labels
36    /// Returns vector of case value identifier names (e.g., ["PROP_NAME",
37    /// "PROP_TITLE"])
38    pub fn case_identifiers(&self) -> Vec<&str> {
39        self.cases
40            .iter()
41            .filter_map(|case| case.label.value.as_ref())
42            .filter_map(|expr| {
43                if let Expression::Identifier(id) = expr {
44                    Some(id.name.as_str())
45                } else {
46                    None
47                }
48            })
49            .collect()
50    }
51
52    /// Check if switch has a default case
53    pub fn has_default_case(&self) -> bool {
54        self.default_case().is_some()
55    }
56
57    /// Get all statements across all case bodies (flattened view)
58    pub fn all_statements(&self) -> impl Iterator<Item = &Statement> {
59        self.cases.iter().flat_map(|case| case.body.iter())
60    }
61
62    /// Find the default case if it exists
63    pub fn default_case(&self) -> Option<&SwitchCase> {
64        self.cases.iter().find(|case| case.label.value.is_none())
65    }
66}