use crate::identifier::Identifier;
use crate::pattern::Pattern;
use crate::statement::Statement;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Function {
id: Option<Identifier>,
params: Vec<Pattern>,
body: Vec<Statement>,
is_async: bool,
is_generator: bool,
}
impl Function {
#[must_use]
pub fn new(
id: Option<Identifier>,
params: Vec<Pattern>,
body: Vec<Statement>,
is_async: bool,
is_generator: bool,
) -> Self {
Self {
id,
params,
body,
is_async,
is_generator,
}
}
#[must_use]
pub fn id(&self) -> Option<&Identifier> {
self.id.as_ref()
}
#[must_use]
pub fn params(&self) -> &[Pattern] {
&self.params
}
#[must_use]
pub fn body(&self) -> &[Statement] {
&self.body
}
#[must_use]
pub fn is_async(&self) -> bool {
self.is_async
}
#[must_use]
pub fn is_generator(&self) -> bool {
self.is_generator
}
}
impl std::fmt::Display for Function {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.is_async {
f.write_str("async ")?;
}
f.write_str("function")?;
if self.is_generator {
f.write_str("*")?;
}
if let Some(name) = &self.id {
write!(f, " {name}")?;
}
let params = self
.params
.iter()
.map(|p| format!("{p}"))
.collect::<Vec<_>>()
.join(", ");
write!(f, "({params}) {{ ... }}")
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ArrowBody {
Expression(Box<crate::expression::Expression>),
Block(Vec<Statement>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ArrowFunction {
params: Vec<Pattern>,
body: ArrowBody,
is_async: bool,
}
impl ArrowFunction {
#[must_use]
pub fn new(params: Vec<Pattern>, body: ArrowBody, is_async: bool) -> Self {
Self {
params,
body,
is_async,
}
}
#[must_use]
pub fn params(&self) -> &[Pattern] {
&self.params
}
#[must_use]
pub fn body(&self) -> &ArrowBody {
&self.body
}
#[must_use]
pub fn is_async(&self) -> bool {
self.is_async
}
}
impl std::fmt::Display for ArrowFunction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.is_async {
f.write_str("async ")?;
}
let params = self
.params
.iter()
.map(|p| format!("{p}"))
.collect::<Vec<_>>()
.join(", ");
write!(f, "({params}) => ")?;
match &self.body {
ArrowBody::Expression(expr) => write!(f, "{expr}"),
ArrowBody::Block(_) => f.write_str("{ ... }"),
}
}
}