xprs 0.1.0

Xprs is a flexible and extensible mathematical expression parser and evaluator for Rust, designed for simplicity and ease of use.
Documentation
/* Built-in imports */
use core::fmt;
/* Crate imports */
use crate::{element::Element, token::Operator};

/// Represents a binary operation in the abstract syntax tree (AST).
#[derive(Debug, PartialOrd, Clone)]
pub struct BinOp<'a> {
    /// The operator of the binary operation.
    pub(crate) op: Operator,
    /// The left-hand side of the binary operation.
    pub(crate) lhs: Element<'a>,
    /// The right-hand side of the binary operation.
    pub(crate) rhs: Element<'a>,
}

impl<'a> BinOp<'a> {
    /// Creates a new [`BinOp`] from the binary operation components.
    const fn new(op: Operator, lhs: Element<'a>, rhs: Element<'a>) -> Self {
        Self { op, lhs, rhs }
    }

    /// Creates a new `Element::BinOp` from the binary operation components.
    pub(crate) fn new_element(
        op: Operator,
        lhs: Element<'a>,
        rhs: Element<'a>,
    ) -> Element<'a> {
        Element::BinOp(Box::new(Self::new(op, lhs, rhs)))
    }
}

impl fmt::Display for BinOp<'_> {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(fmt, "({} {} {})", self.lhs, self.op, self.rhs)
    }
}

impl PartialEq for BinOp<'_> {
    #[allow(clippy::unreachable)]
    fn eq(&self, other: &Self) -> bool {
        self.op == other.op
            && match self.op {
                // non commutative operators
                Operator::Divide
                | Operator::Minus
                | Operator::Modulo
                | Operator::Power => {
                    self.lhs == other.lhs && self.rhs == other.rhs
                },
                // commutative operators
                Operator::Plus | Operator::Times => {
                    (self.lhs == other.lhs && self.rhs == other.rhs)
                        || (self.lhs == other.rhs && self.rhs == other.lhs)
                },
                // not a binary operator
                Operator::Factorial => unreachable!(),
            }
    }
}