use crate::syntax::ast::node::Node;
use boa_interner::{Interner, ToInternedString};
use crate::syntax::ast::node::StatementList;
#[cfg(feature = "deser")]
use serde::{Deserialize, Serialize};
#[cfg(test)]
mod tests;
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct Case {
condition: Node,
body: StatementList,
}
impl Case {
pub fn new<C, B>(condition: C, body: B) -> Self
where
C: Into<Node>,
B: Into<StatementList>,
{
Self {
condition: condition.into(),
body: body.into(),
}
}
pub fn condition(&self) -> &Node {
&self.condition
}
pub fn body(&self) -> &StatementList {
&self.body
}
}
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct Switch {
val: Box<Node>,
cases: Box<[Case]>,
default: Option<StatementList>,
}
impl Switch {
pub fn new<V, C, D>(val: V, cases: C, default: Option<D>) -> Self
where
V: Into<Node>,
C: Into<Box<[Case]>>,
D: Into<StatementList>,
{
Self {
val: Box::new(val.into()),
cases: cases.into(),
default: default.map(D::into),
}
}
pub fn val(&self) -> &Node {
&self.val
}
pub fn cases(&self) -> &[Case] {
&self.cases
}
pub fn default(&self) -> Option<&[Node]> {
self.default.as_ref().map(StatementList::items)
}
pub(in crate::syntax::ast::node) fn to_indented_string(
&self,
interner: &Interner,
indentation: usize,
) -> String {
let indent = " ".repeat(indentation);
let mut buf = format!("switch ({}) {{\n", self.val().to_interned_string(interner));
for e in self.cases().iter() {
buf.push_str(&format!(
"{} case {}:\n{}",
indent,
e.condition().to_interned_string(interner),
e.body().to_indented_string(interner, indentation + 2)
));
}
if let Some(ref default) = self.default {
buf.push_str(&format!(
"{indent} default:\n{}",
default.to_indented_string(interner, indentation + 2)
));
}
buf.push_str(&format!("{indent}}}"));
buf
}
}
impl ToInternedString for Switch {
fn to_interned_string(&self, interner: &Interner) -> String {
self.to_indented_string(interner, 0)
}
}
impl From<Switch> for Node {
fn from(switch: Switch) -> Self {
Self::Switch(switch)
}
}