#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum Arity {
Exact(usize),
Range(usize, usize),
AtLeast(usize),
}
impl Arity {
pub(crate) fn accepts(self, argc: usize) -> bool {
match self {
Arity::Exact(n) => argc == n,
Arity::Range(min, max) => (min..=max).contains(&argc),
Arity::AtLeast(min) => argc >= min,
}
}
}
#[derive(Clone, Copy, Debug)]
pub(crate) struct Builtin {
pub(crate) name: &'static str,
pub(crate) arity: Arity,
}
pub(crate) const BUILTINS: &[Builtin] = &[
Builtin {
name: "len",
arity: Arity::Exact(1),
},
Builtin {
name: "empty",
arity: Arity::Exact(1),
},
Builtin {
name: "keys",
arity: Arity::Exact(1),
},
Builtin {
name: "values",
arity: Arity::Exact(1),
},
Builtin {
name: "trim",
arity: Arity::Exact(1),
},
Builtin {
name: "to_string",
arity: Arity::Exact(1),
},
Builtin {
name: "to_int",
arity: Arity::Exact(1),
},
Builtin {
name: "to_float",
arity: Arity::Exact(1),
},
Builtin {
name: "json_parse",
arity: Arity::Exact(1),
},
Builtin {
name: "contains",
arity: Arity::Exact(2),
},
Builtin {
name: "grep_text",
arity: Arity::Exact(2),
},
Builtin {
name: "starts_with",
arity: Arity::Exact(2),
},
Builtin {
name: "ends_with",
arity: Arity::Exact(2),
},
Builtin {
name: "split",
arity: Arity::Exact(2),
},
Builtin {
name: "join",
arity: Arity::Exact(2),
},
Builtin {
name: "validate",
arity: Arity::Exact(2),
},
Builtin {
name: "ceil_div",
arity: Arity::Exact(2),
},
Builtin {
name: "floor_div",
arity: Arity::Exact(2),
},
Builtin {
name: "push",
arity: Arity::Exact(2),
},
Builtin {
name: "slice",
arity: Arity::Exact(3),
},
Builtin {
name: "find",
arity: Arity::Range(2, 3),
},
Builtin {
name: "format",
arity: Arity::AtLeast(1),
},
Builtin {
name: "range",
arity: Arity::Range(1, 3),
},
];
pub(crate) fn lookup(name: &str) -> Option<Builtin> {
BUILTINS
.iter()
.copied()
.find(|builtin| builtin.name == name)
}
pub(crate) fn is_builtin(name: &str) -> bool {
lookup(name).is_some()
}