use crate::diagnostics::Spanned;
use serde::{Deserialize, Serialize};
use std::fmt;
use super::Expr;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Formals {
Fixed(Vec<String>),
Variable(String),
Mixed {
fixed: Vec<String>,
rest: String,
},
Keyword {
fixed: Vec<String>,
rest: Option<String>,
keywords: Vec<KeywordParam>,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct KeywordParam {
pub name: String,
pub default: Option<Spanned<Expr>>,
}
impl fmt::Display for Formals {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Formals::Fixed(params) => {
write!(f, "(")?;
for (i, param) in params.iter().enumerate() {
if i > 0 { write!(f, " ")?; }
write!(f, "{param}")?;
}
write!(f, ")")
}
Formals::Variable(param) => write!(f, "{param}"),
Formals::Mixed { fixed, rest } => {
write!(f, "(")?;
for (i, param) in fixed.iter().enumerate() {
if i > 0 { write!(f, " ")?; }
write!(f, "{param}")?;
}
write!(f, " . {rest})")
}
Formals::Keyword { fixed, rest, keywords } => {
write!(f, "(")?;
for (i, param) in fixed.iter().enumerate() {
if i > 0 { write!(f, " ")?; }
write!(f, "{param}")?;
}
if let Some(rest) = rest {
if !fixed.is_empty() { write!(f, " ")?; }
write!(f, ". {rest}")?;
}
for kw in keywords {
write!(f, " #{} {}", kw.name, kw.name)?;
if let Some(default) = &kw.default {
write!(f, " {}", default.inner)?;
}
}
write!(f, ")")
}
}
}
}