use serde::Serialize;
use crate::model::{BinaryExpression, Expression, SourceLocation, Statement};
#[derive(Debug, Clone, Serialize)]
pub struct IfStatement {
pub condition: Expression,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub then_body: Vec<Statement>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub then_has_braces: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub else_body: Option<Vec<Statement>>,
pub location: SourceLocation,
}
impl IfStatement {
pub fn extract_null_check_variable(&self) -> Option<&str> {
match &self.condition {
Expression::Binary(bin) if bin.is_null_check() => bin.extract_compared_variable(),
expr => expr.extract_variable_name(),
}
}
pub fn extract_nonzero_check_variable(&self) -> Option<&str> {
match &self.condition {
Expression::Binary(bin) => {
if is_nonzero_comparison(bin) {
bin.extract_compared_variable()
} else {
None
}
}
expr => expr.extract_variable_name(),
}
}
pub fn is_truthiness_check(&self) -> bool {
matches!(&self.condition, Expression::Identifier(_))
}
pub fn has_single_statement(&self) -> bool {
self.then_body.len() == 1
}
pub fn has_else(&self) -> bool {
self.else_body.is_some()
}
}
fn is_nonzero_comparison(bin: &BinaryExpression) -> bool {
match bin.operator.as_str() {
"!=" | ">" | "<" => {
bin.left.is_zero() || bin.right.is_zero()
}
_ => false,
}
}