use super::*;
use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct FunctionBindings<'f> {
entries: HashMap<String, FunctionOverloads<Function<'f>>>,
}
impl<'f> FunctionBindings<'f> {
pub fn new() -> Self {
Self {
entries: HashMap::new(),
}
}
}
impl<'f> FunctionBindings<'f> {
pub fn bind<F, Fm, Args>(
&mut self,
name: impl Into<String>,
member: bool,
f: F,
) -> Result<&mut Self, Error>
where
F: IntoFunction<'f, Fm, Args>,
Fm: FnMarker,
Args: Arguments,
{
let name = name.into();
if member && Args::LEN == 0 {
return Err(Error::invalid_argument("Member functions cannot have zero arguments"));
}
let entry = self
.entries
.entry(name)
.or_insert_with(FunctionOverloads::new);
entry.add(member, f.into_function())?;
Ok(self)
}
pub fn bind_member<F, Fm, Args>(
&mut self,
name: impl Into<String>,
f: F,
) -> Result<&mut Self, Error>
where
F: IntoFunction<'f, Fm, Args>,
Fm: FnMarker,
Args: Arguments + NonEmptyArguments,
{
self.bind(name, true, f)
}
pub fn bind_global<F, Fm, Args>(
&mut self,
name: impl Into<String>,
f: F,
) -> Result<&mut Self, Error>
where
F: IntoFunction<'f, Fm, Args>,
Fm: FnMarker,
Args: Arguments,
{
self.bind(name, false, f)
}
pub fn find(&self, name: &str) -> Option<&FunctionOverloads<Function<'f>>> {
self.entries.get(name)
}
pub fn find_mut(&mut self, name: &str) -> Option<&mut FunctionOverloads<Function<'f>>> {
self.entries.get_mut(name)
}
pub fn entries(&self) -> impl Iterator<Item = (&str, &FunctionOverloads<Function<'f>>)> {
self.entries
.iter()
.map(|(name, entry)| (name.as_str(), entry))
}
pub fn entries_mut(
&mut self,
) -> impl Iterator<Item = (&str, &mut FunctionOverloads<Function<'f>>)> {
self.entries
.iter_mut()
.map(|(name, entry)| (name.as_str(), entry))
}
pub fn remove(&mut self, name: &str) -> Result<(), Error> {
if self.entries.remove(name).is_none() {
return Err(Error::not_found(format!("Function {name} not found")));
}
Ok(())
}
pub fn clear(&mut self) {
self.entries.clear();
}
}