use alloc::format;
use alloc::string::String;
use core::fmt::{Debug, Display, Formatter};
use deep_causality_core::{CausalityError, CausalityErrorEnum};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PhysicsError(pub PhysicsErrorEnum);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum PhysicsErrorEnum {
PhysicalInvariantBroken(String),
DimensionMismatch(String),
CausalityViolation(String),
MetricSingularity(String),
NormalizationError(String),
ZeroKelvinViolation,
EntropyViolation(String),
Singularity(String),
NumericalInstability(String),
NotConverged(String),
CalculationError(String),
MetricConventionError(String),
TopologyError(String),
}
impl PhysicsError {
pub(crate) fn new(variant: PhysicsErrorEnum) -> Self {
Self(variant)
}
#[allow(non_snake_case)]
pub fn PhysicalInvariantBroken(msg: String) -> Self {
Self(PhysicsErrorEnum::PhysicalInvariantBroken(msg))
}
#[allow(non_snake_case)]
pub fn DimensionMismatch(msg: String) -> Self {
Self(PhysicsErrorEnum::DimensionMismatch(msg))
}
#[allow(non_snake_case)]
pub fn CausalityViolation(msg: String) -> Self {
Self(PhysicsErrorEnum::CausalityViolation(msg))
}
#[allow(non_snake_case)]
pub fn MetricSingularity(msg: String) -> Self {
Self(PhysicsErrorEnum::MetricSingularity(msg))
}
#[allow(non_snake_case)]
pub fn NormalizationError(msg: String) -> Self {
Self(PhysicsErrorEnum::NormalizationError(msg))
}
#[allow(non_snake_case)]
pub fn ZeroKelvinViolation() -> Self {
Self(PhysicsErrorEnum::ZeroKelvinViolation)
}
#[allow(non_snake_case)]
pub fn EntropyViolation(msg: String) -> Self {
Self(PhysicsErrorEnum::EntropyViolation(msg))
}
#[allow(non_snake_case)]
pub fn Singularity(msg: String) -> Self {
Self(PhysicsErrorEnum::Singularity(msg))
}
#[allow(non_snake_case)]
pub fn NotConverged(msg: String) -> Self {
Self(PhysicsErrorEnum::NotConverged(msg))
}
#[allow(non_snake_case)]
pub fn NumericalInstability(msg: String) -> Self {
Self(PhysicsErrorEnum::NumericalInstability(msg))
}
#[allow(non_snake_case)]
pub fn CalculationError(msg: String) -> Self {
Self(PhysicsErrorEnum::CalculationError(msg))
}
#[allow(non_snake_case)]
pub fn MetricConventionError(msg: String) -> Self {
Self(PhysicsErrorEnum::MetricConventionError(msg))
}
#[allow(non_snake_case)]
pub fn TopologyError(msg: String) -> Self {
Self(PhysicsErrorEnum::TopologyError(msg))
}
}
impl From<PhysicsError> for CausalityError {
fn from(e: PhysicsError) -> Self {
CausalityError::new(CausalityErrorEnum::Custom(format!("{}", e)))
}
}
impl From<deep_causality_tensor::CausalTensorError> for PhysicsError {
fn from(e: deep_causality_tensor::CausalTensorError) -> Self {
PhysicsError::new(PhysicsErrorEnum::Singularity(format!(
"Tensor Error: {:?}",
e
)))
}
}
impl From<deep_causality_metric::MetricError> for PhysicsError {
fn from(e: deep_causality_metric::MetricError) -> Self {
PhysicsError::new(PhysicsErrorEnum::MetricConventionError(format!("{}", e)))
}
}
impl From<deep_causality_linear::LinearError> for PhysicsError {
fn from(error: deep_causality_linear::LinearError) -> Self {
use deep_causality_linear::LinearErrorEnum;
let message = format!("{error}");
match error.kind() {
LinearErrorEnum::IndexOutOfBounds { .. }
| LinearErrorEnum::ShapeMismatch { .. }
| LinearErrorEnum::InnerDimensionMismatch { .. }
| LinearErrorEnum::LengthMismatch { .. }
| LinearErrorEnum::NotSquare { .. }
| LinearErrorEnum::EmptyMatrix => Self::DimensionMismatch(message),
_ => Self::NumericalInstability(message),
}
}
}
impl From<deep_causality_topology::TopologyError> for PhysicsError {
fn from(error: deep_causality_topology::TopologyError) -> Self {
use deep_causality_topology::TopologyErrorEnum;
let message = format!("{error}");
match error.0 {
TopologyErrorEnum::DimensionMismatch(_)
| TopologyErrorEnum::InvalidGradeOperation(_)
| TopologyErrorEnum::IndexOutOfBounds(_)
| TopologyErrorEnum::SimplexNotFound => Self::DimensionMismatch(message),
_ => Self::CalculationError(message),
}
}
}
impl From<deep_causality_stats::StatsError> for PhysicsError {
fn from(error: deep_causality_stats::StatsError) -> Self {
use deep_causality_stats::StatsErrorEnum;
let message = format!("{error}");
match error.kind() {
StatsErrorEnum::EmptyInput(_) | StatsErrorEnum::DimensionMismatch(_) => {
Self::DimensionMismatch(message)
}
StatsErrorEnum::NegativeProbability(_) => Self::NormalizationError(message),
StatsErrorEnum::NotConverged { .. } => Self::NotConverged(message),
_ => Self::NumericalInstability(message),
}
}
}
impl Display for PhysicsError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match &self.0 {
PhysicsErrorEnum::PhysicalInvariantBroken(msg) => {
write!(f, "Physical Invariant Broken: {}", msg)
}
PhysicsErrorEnum::DimensionMismatch(msg) => write!(f, "Dimension Mismatch: {}", msg),
PhysicsErrorEnum::CausalityViolation(msg) => write!(f, "Causality Violation: {}", msg),
PhysicsErrorEnum::MetricSingularity(msg) => write!(f, "Metric Singularity: {}", msg),
PhysicsErrorEnum::NormalizationError(msg) => write!(f, "Normalization Error: {}", msg),
PhysicsErrorEnum::ZeroKelvinViolation => {
write!(f, "Zero Kelvin Violation: Temperature cannot be negative")
}
PhysicsErrorEnum::EntropyViolation(msg) => write!(f, "Entropy Violation: {}", msg),
PhysicsErrorEnum::Singularity(msg) => write!(f, "Singularity: {}", msg),
PhysicsErrorEnum::NumericalInstability(msg) => {
write!(f, "Numerical Instability: {}", msg)
}
PhysicsErrorEnum::NotConverged(msg) => {
write!(f, "Solver did not converge: {}", msg)
}
PhysicsErrorEnum::CalculationError(msg) => write!(f, "Calculation Error: {}", msg),
PhysicsErrorEnum::MetricConventionError(msg) => {
write!(f, "Metric Convention Error: {}", msg)
}
PhysicsErrorEnum::TopologyError(msg) => {
write!(f, "Topology Error: {}", msg)
}
}
}
}