use pine_ast::Literal;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParamType {
Number,
String,
Bool,
Color,
Any,
}
impl ParamType {
pub fn accepts(self, literal: &Literal) -> bool {
match self {
ParamType::Any => true,
_ if matches!(literal, Literal::Na) => true,
ParamType::Number | ParamType::Bool => {
!matches!(literal, Literal::String(_) | Literal::HexColor(_))
}
ParamType::String => true,
ParamType::Color => matches!(literal, Literal::HexColor(_) | Literal::String(_)),
}
}
pub fn describe(self) -> &'static str {
match self {
ParamType::Number => "a number",
ParamType::String => "a string",
ParamType::Bool => "a bool",
ParamType::Color => "a color",
ParamType::Any => "a value",
}
}
}
#[derive(Debug, Clone)]
pub struct Param {
pub name: String,
pub ty: ParamType,
pub required: bool,
pub variadic: bool,
pub lazy: bool,
}
#[derive(Debug, Clone, Default)]
pub struct BuiltinSignature {
pub params: Vec<Param>,
}
impl BuiltinSignature {
pub fn positional(&self, index: usize) -> Option<&Param> {
match self.params.get(index) {
Some(param) => Some(param),
None => self.params.last().filter(|last| last.variadic),
}
}
pub fn named(&self, name: &str) -> Option<&Param> {
self.params.iter().find(|param| param.name == name)
}
pub fn positional_is_lazy(&self, index: usize) -> bool {
self.positional(index).is_some_and(|param| param.lazy)
}
pub fn named_is_lazy(&self, name: &str) -> bool {
self.named(name).is_some_and(|param| param.lazy)
}
pub fn max_positional(&self) -> Option<usize> {
if self.params.last().is_some_and(|last| last.variadic) {
None
} else {
Some(self.params.len())
}
}
}