val 0.6.0

An arbitrary precision calculator language
Documentation
use super::*;

pub struct BuiltinFunctionPayload<'a> {
  pub arguments: Vec<Value>,
  pub config: Config,
  pub name: &'static str,
  pub span: &'a Span,
}

impl BuiltinFunctionPayload<'_> {
  pub(crate) fn format_arguments(&self) -> String {
    self
      .arguments
      .iter()
      .map(|argument| argument.display(self.config))
      .collect::<Vec<_>>()
      .join(" ")
  }

  pub(crate) fn integer(&self, index: usize) -> Result<Integer> {
    self.number(index)?.to_integer().ok_or_else(|| {
      Error::new(
        self.span,
        format!("Arguments to `{}` must be finite integers", self.name),
      )
    })
  }

  pub(crate) fn logarithm_argument(&self, index: usize) -> Result<&Number> {
    let number = self.number(index)?;

    if number.is_zero() || number.is_negative() {
      return Err(Error::new(
        self.span,
        "Cannot take logarithm of zero or negative number",
      ));
    }

    Ok(number)
  }

  pub(crate) fn number(&self, index: usize) -> Result<&Number> {
    self.arguments[index].number(self.span)
  }
}