use std::fmt::{self, Display, Write};
use crate::{Block, Expr, Formatter};
#[derive(Debug, Clone)]
pub struct Switch {
cond: Expr,
cases: Vec<(Expr, Block)>,
default: Option<Block>,
}
impl Switch {
pub fn new(cond: &Expr) -> Self {
Self {
cond: cond.clone(),
cases: Vec::new(),
default: None,
}
}
pub fn set_default(&mut self, default: Block) -> &mut Self {
self.default = Some(default);
self
}
pub fn new_case(&mut self, label: Expr) -> &mut Block {
self.cases.push((label, Block::new()));
if let Some((_, block)) = self.cases.last_mut() {
block
} else {
unreachable!()
}
}
pub fn case(&mut self, label: Expr, block: Block) -> &mut Self {
self.cases.push((label, block));
self
}
pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
write!(fmt, "switch (")?;
self.cond.fmt(fmt)?;
writeln!(fmt, ") {{")?;
for (label, block) in self.cases.iter() {
writeln!(fmt, "case {}:", label)?;
fmt.block(|f| block.fmt(f))?;
writeln!(fmt, "\nbreak;")?;
}
if let Some(def) = &self.default {
writeln!(fmt, "default: ")?;
fmt.block(|f| def.fmt(f))?;
writeln!(fmt)?;
}
writeln!(fmt, "}}")
}
}
impl Display for Switch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut ret = String::new();
self.fmt(&mut Formatter::new(&mut ret)).unwrap();
write!(f, "{ret}")
}
}