use crate::number::Number;
use std::borrow::Cow;
use thiserror::Error;
#[cfg(feature = "decimal-precision")]
mod decimal;
#[cfg(feature = "f64-floats")]
mod f64;
#[derive(Error, Debug, Clone)]
pub enum FuncError {
#[error("Conversion error: failed to convert number to f64")]
ToF64Conversion,
#[error("Conversion error: failed to convert f64 result back to number")]
FromF64Conversion,
#[error("Square root of negative number: {value}")]
NegativeSqrt { value: Number },
#[error("Domain error in function '{function}': invalid input {input}")]
DomainError { function: String, input: Number },
#[error("Math error: {message}")]
MathError { message: String },
}
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum SymbolError {
#[error("Duplicate symbol definition: '{0}'")]
DuplicateSymbol(String),
#[error("Symbol '{0}' not found")]
SymbolNotFound(String),
}
#[derive(Debug, Clone)]
pub enum Symbol {
Const {
name: Cow<'static, str>,
value: Number,
description: Option<Cow<'static, str>>,
local: bool,
},
Func {
name: Cow<'static, str>,
args: usize,
variadic: bool,
callback: fn(&[Number]) -> Result<Number, FuncError>,
description: Option<Cow<'static, str>>,
local: bool,
},
}
impl Symbol {
pub fn name(&self) -> &str {
match self {
Symbol::Const { name, .. } => name,
Symbol::Func { name, .. } => name,
}
}
pub fn description(&self) -> Option<&str> {
match self {
Symbol::Const { description, .. } => description.as_deref(),
Symbol::Func { description, .. } => description.as_deref(),
}
}
pub fn is_local(&self) -> bool {
match self {
Symbol::Const { local, .. } => *local,
Symbol::Func { local, .. } => *local,
}
}
}