use crate::expr::Kind;
#[allow(unused)]
#[derive(Debug, Clone)]
pub struct ArgSpec {
pub name: &'static str,
pub kind: Kind,
pub optional: bool,
}
#[derive(Debug, Clone)]
pub struct Signature {
pub args: Vec<ArgSpec>,
pub variadic: Option<Kind>,
pub returns: Kind,
}
impl Signature {
pub fn new() -> Self {
Self {
args: Vec::new(),
variadic: None,
returns: Kind::Any,
}
}
pub fn arg(mut self, name: &'static str, kind: Kind) -> Self {
self.args.push(ArgSpec {
name,
kind,
optional: false,
});
self
}
pub fn optional(mut self, name: &'static str, kind: Kind) -> Self {
self.args.push(ArgSpec {
name,
kind,
optional: true,
});
self
}
pub fn variadic(mut self, kind: Kind) -> Self {
self.variadic = Some(kind);
self
}
pub fn returns(mut self, kind: Kind) -> Self {
self.returns = kind;
self
}
#[allow(unused)]
pub fn arity(&self) -> (usize, Option<usize>) {
let lower = self.args.iter().filter(|a| !a.optional).count();
let upper = if self.variadic.is_some() {
None
} else {
Some(self.args.len())
};
(lower, upper)
}
}
impl Default for Signature {
fn default() -> Self {
Self::new()
}
}