use crate::module::ModuleItem;
use crate::span::Spanned;
use crate::statement::Statement;
pub type Program = Spanned<ProgramKind>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProgramKind {
Script {
body: Vec<Statement>,
},
Module {
body: Vec<ModuleItem>,
},
}
impl ProgramKind {
#[must_use]
pub fn script(body: Vec<Statement>) -> Self {
Self::Script { body }
}
#[must_use]
pub fn module(body: Vec<ModuleItem>) -> Self {
Self::Module { body }
}
}
impl std::fmt::Display for ProgramKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Script { body } => write_items(f, "Script", body.iter().map(|s| format!("{s}"))),
Self::Module { body } => write_items(f, "Module", body.iter().map(|m| format!("{m}"))),
}
}
}
fn write_items<I: Iterator<Item = String>>(
f: &mut std::fmt::Formatter<'_>,
kind: &str,
items: I,
) -> std::fmt::Result {
write!(f, "{kind} {{ ")?;
let body = items.collect::<Vec<_>>().join("; ");
write!(f, "{body} }}")
}