Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Nonanti/mathcore/llms.txt

Use this file to discover all available pages before exploring further.

Every fallible operation in MathCore returns Result<T, MathError>. Whether you are parsing an expression string, evaluating with runtime variables, differentiating symbolically, or solving an equation, MathError is the single error type you will encounter. It is derived with thiserror, which means it automatically implements both std::error::Error and Display using the #[error("…")] message defined on each variant. This makes MathError composable with any error-handling strategy — direct match, the ? operator, anyhow, eyre, or your own custom error type.

pub enum MathError

#[derive(Debug, thiserror::Error)]
pub enum MathError {
    #[error("Parse error: {0}")]
    ParseError(String),

    #[error("Undefined variable: {0}")]
    UndefinedVariable(String),

    #[error("Undefined function: {0}")]
    UndefinedFunction(String),

    #[error("Invalid operation: {0}")]
    InvalidOperation(String),

    #[error("Division by zero")]
    DivisionByZero,

    #[error("Invalid argument count for function {0}: expected {1}, got {2}")]
    InvalidArgumentCount(String, usize, usize),

    #[error("Cannot solve equation: {0}")]
    SolverError(String),

    #[error("Numeric overflow")]
    Overflow,
}

Variants

ParseError(String)

Display: "Parse error: {message}" Returned when the input expression string cannot be turned into a valid Expr tree. The inner String contains a human-readable description of the parse failure — for example, unexpected tokens, mismatched parentheses, or an empty input. Common causes
  • Mismatched or missing parentheses: "sin(x", "(2 + 3"
  • Unknown or malformed token sequences: "2 ** 3", "x ++ 1"
  • Empty string input
use mathcore::{MathCore, MathError};

match MathCore::parse("sin(x") {
    Err(MathError::ParseError(msg)) => {
        println!("Could not parse expression: {}", msg);
    }
    _ => {}
}

UndefinedVariable(String)

Display: "Undefined variable: {name}" Returned during evaluation when the expression contains a Symbol that is not bound in the active context or variable map. The inner String is the variable name. Common causes
  • Forgetting to supply a variable in evaluate_with_vars
  • Typo in a variable name ("X" vs "x")
use mathcore::{MathCore, MathError, HashMap};

let math = MathCore::new();
let vars: HashMap<String, f64> = HashMap::new(); // "x" not provided

match math.evaluate_with_vars("x + 1", &vars) {
    Err(MathError::UndefinedVariable(name)) => {
        println!("Variable '{}' is not defined", name);
    }
    _ => {}
}

UndefinedFunction(String)

Display: "Undefined function: {name}" Returned when the expression calls a function name that the engine does not recognise and that has not been registered as a custom function in the Context. The inner String is the function name as it appeared in the expression. Common causes
  • Misspelling a built-in function name: "sinn(x)", "Cos(x)"
  • Using a function name before registering it in a Context
use mathcore::{MathCore, MathError};

match MathCore::parse("foo(x)").and_then(|_| {
    MathCore::differentiate("foo(x)", "x")
}) {
    Err(MathError::UndefinedFunction(name)) => {
        println!("Function '{}' is not known", name);
    }
    _ => {}
}

InvalidOperation(String)

Display: "Invalid operation: {message}" Returned when an operation is structurally valid but cannot be applied to the given expression type. The inner String provides context. For example, calculate returns this when evaluation produces a non-numeric Expr (such as a complex or symbolic result), and plot_ascii returns this when no finite points can be computed. Common causes
  • Calling calculate on an expression that evaluates to a Complex result
  • Calling plot_ascii on a range where every sampled point is non-finite
  • Applying a numeric operation to a still-symbolic expression
use mathcore::{MathCore, MathError};

// An expression with an unresolved symbol cannot reduce to f64
let math = MathCore::new();
match math.calculate("x + 1") {
    Err(MathError::InvalidOperation(msg)) |
    Err(MathError::UndefinedVariable(msg)) => {
        println!("Operation failed: {}", msg);
    }
    _ => {}
}

DivisionByZero

Display: "Division by zero" Returned when the engine detects a division by zero at evaluation time. This variant carries no inner data — the error message is always the same.
Note that simplify guards against division by zero during constant folding using an f64::EPSILON check rather than an exact zero comparison. Only the evaluation engine raises DivisionByZero.
use mathcore::{MathCore, MathError};

let math = MathCore::new();
match math.calculate("1 / 0") {
    Ok(v)                        => println!("result: {}", v),
    Err(MathError::DivisionByZero) => println!("cannot divide by zero"),
    Err(e)                       => println!("other error: {}", e),
}

InvalidArgumentCount(String, usize, usize)

Display: "Invalid argument count for function {name}: expected {expected}, got {got}" Returned when a function call in the expression supplies the wrong number of arguments. The three fields are the function name, the expected arity, and the actual arity. Common causes
  • "sin(x, y)"sin expects exactly 1 argument
  • "atan2(x)"atan2 expects exactly 2 arguments
use mathcore::{MathCore, MathError};

match MathCore::parse("sin(x, y)").and_then(|_| {
    let math = mathcore::MathCore::new();
    math.evaluate("sin(x, y)")
}) {
    Err(MathError::InvalidArgumentCount(name, expected, got)) => {
        println!(
            "'{}' expects {} argument(s), but {} were given",
            name, expected, got
        );
    }
    _ => {}
}

SolverError(String)

Display: "Cannot solve equation: {message}" Returned by the solver subsystem when the equation has no solution, has infinitely many solutions, or uses a form the solver does not support. The inner String explains the specific failure. Common causes
  • No real roots exist: "x^2 + 1" has no real solutions
  • Transcendental equations the symbolic solver cannot handle: "sin(x) - x"
  • Expressions that are not polynomial in the specified variable
use mathcore::{MathCore, MathError};

match MathCore::solve("x^2 + 1", "x") {
    Ok(roots)                     => println!("roots: {:?}", roots),
    Err(MathError::SolverError(msg)) => println!("solver failed: {}", msg),
    Err(e)                        => println!("error: {}", e),
}

Overflow

Display: "Numeric overflow" Returned when a calculation produces a value too large to represent as an f64 (i.e. the result is f64::INFINITY or f64::NEG_INFINITY due to overflow, rather than a mathematically infinite value). Common causes
  • Factorial of a very large number
  • Exponentiation with extremely large exponents
use mathcore::{MathCore, MathError};

let math = MathCore::new();
match math.calculate("1e308 * 1e308") {
    Err(MathError::Overflow) => println!("numeric overflow"),
    Ok(v)                    => println!("result: {}", v),
    Err(e)                   => println!("other error: {}", e),
}

Pattern matching

MathError is an ordinary Rust enum, so you can match exhaustively or selectively. The most common pattern is a match over the Result returned by any MathCore method:
use mathcore::{MathCore, MathError};

match MathCore::parse("1 / 0").and_then(|_| {
    MathCore::new().calculate("1 / 0")
}) {
    Ok(v)                            => println!("result: {}", v),
    Err(MathError::DivisionByZero)   => println!("cannot divide by zero"),
    Err(MathError::ParseError(msg))  => println!("parse error: {}", msg),
    Err(e)                           => println!("other error: {}", e),
}

Using the ? operator

Because MathError implements std::error::Error, it works naturally with the ? operator inside functions that return Result<_, MathError> or any error type that MathError converts into:
use mathcore::{MathCore, MathError};

fn compute(expr: &str) -> Result<f64, MathError> {
    let math = MathCore::new();
    let result = math.calculate(expr)?;
    Ok(result)
}

fn differentiate_and_evaluate(expression: &str, x: f64) -> Result<f64, MathError> {
    // Differentiate symbolically
    let deriv = MathCore::differentiate(expression, "x")?;

    // Evaluate the derivative at x
    let math = MathCore::new();
    let mut vars = mathcore::HashMap::new();
    vars.insert("x".to_string(), x);
    math.evaluate_with_vars(&deriv.to_string(), &vars)
}

Display and std::error::Error

All variants produce a consistent error message through Display, thanks to thiserror. You can log, format, or propagate them like any other Rust error:
use mathcore::{MathCore, MathError};

fn run(expr: &str) {
    match MathCore::new().calculate(expr) {
        Ok(v)  => println!("{} = {}", expr, v),
        Err(e) => eprintln!("Error evaluating '{}': {}", expr, e),
        // e.g. "Error evaluating 'foo(': Parse error: unexpected end of input"
    }
}
When integrating MathCore into a larger application, consider wrapping MathError with anyhow::Error or your own domain error type using the From<MathError> trait. All thiserror-derived enums are compatible with both crates out of the box.

Build docs developers (and LLMs) love