conspire 0.6.0

The Rust interface to conspire.
Documentation
//! Constitutive model library.

#[cfg(test)]
pub mod test;

pub mod cohesive;
pub mod fluid;
pub mod hybrid;
pub mod multiphysics;
pub mod solid;
pub mod thermal;

use crate::{
    defeat_message,
    math::{Scalar, TensorError, TestError},
};
use std::fmt::{self, Debug, Display, Formatter};

/// Required methods for constitutive models.
pub trait Constitutive
where
    Self: Clone + Debug,
{
}

/// Possible errors encountered in constitutive models.
pub enum ConstitutiveError {
    Custom(String, String),
    InvalidJacobian(Scalar, String),
    Upstream(String, String),
}

impl From<ConstitutiveError> for TestError {
    fn from(error: ConstitutiveError) -> Self {
        Self {
            message: error.to_string(),
        }
    }
}

impl From<TensorError> for ConstitutiveError {
    fn from(error: TensorError) -> Self {
        ConstitutiveError::Custom(
            error.to_string(),
            "unknown (temporary error handling)".to_string(),
        )
    }
}

impl From<ConstitutiveError> for String {
    fn from(error: ConstitutiveError) -> Self {
        Self::from(&error)
    }
}

impl From<&ConstitutiveError> for String {
    fn from(error: &ConstitutiveError) -> Self {
        match error {
            ConstitutiveError::Custom(message, constitutive_model) => format!(
                "\x1b[1;91m{message}\x1b[0;91m\n\
                        In constitutive model: {constitutive_model}."
            ),
            ConstitutiveError::InvalidJacobian(jacobian, constitutive_model) => format!(
                "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
                        In constitutive model: {constitutive_model}."
            ),
            ConstitutiveError::Upstream(error, constitutive_model) => format!(
                "{error}\x1b[0;91m\n\
                    In constitutive model: {constitutive_model}."
            ),
        }
    }
}

impl Debug for ConstitutiveError {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "\n{}\n\x1b[0;2;31m{}\x1b[0m\n",
            String::from(self),
            defeat_message()
        )
    }
}

impl Display for ConstitutiveError {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{}\x1b[0m", String::from(self))
    }
}

impl PartialEq for ConstitutiveError {
    fn eq(&self, other: &Self) -> bool {
        match self {
            Self::Custom(a, b) => match other {
                Self::Custom(c, d) => a == c && b == d,
                _ => false,
            },
            Self::InvalidJacobian(a, b) => match other {
                Self::InvalidJacobian(c, d) => a == c && b == d,
                _ => false,
            },
            Self::Upstream(a, b) => match other {
                Self::Upstream(c, d) => a == c && b == d,
                _ => false,
            },
        }
    }
}