ihateintegrals 0.1.2

A computer algebra library for solving integrals.
Documentation
use core::fmt;
use std::sync::Arc;

use serde_json::json;

use super::{Expression, IExpression, EXPRESSION_INSTANCES};

#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub enum Constant {
    Euler,
    Pi,
    Imaginary,
}

#[derive(PartialEq, Eq, Hash)]
pub struct ConstantExp {
    value: Constant,
}

impl ConstantExp {
    pub fn of(value: Constant) -> Expression {
        let id = format!("Const{:?}", value);

        let mut instances = EXPRESSION_INSTANCES.lock().unwrap();

        if let Some(result) = instances.get(&id) {
            return result.clone();
        }

        let result = Expression::ConstantExp(Arc::new(ConstantExp { value }));

        instances.insert(id, result.clone());
        result
    }

    pub fn value(&self) -> Constant {
        self.value
    }
}

impl IExpression for ConstantExp {
    fn to_unambigious_string(&self) -> String {
        format!("{:?}", self.value)
    }

    fn id(&self) -> String {
        format!("Const{:?}", self.value)
    }

    fn to_json(&self) -> serde_json::Value {
        json!(match self.value {
            Constant::Euler => "E",
            Constant::Pi => "Pi",
            Constant::Imaginary => "ImaginaryUnit",
        })
    }
}

impl fmt::Debug for ConstantExp {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.to_json())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn flywheel() {
        let a = ConstantExp::of(Constant::Euler);
        let b = ConstantExp::of(Constant::Euler);
        assert_eq!(a, b);
        let c = ConstantExp::of(Constant::Pi);
        assert_ne!(a, c);
    }
}