use derive_new::new;
use schemars::JsonSchema;
use std::fmt;
use utoipa::ToSchema;
pub mod operator;
use operator::Operator;
use serde::{Deserialize, Serialize};
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct Mi(pub String);
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct Mrow(pub Vec<MathExpression>);
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub enum Type {
Integer,
Rational,
Real,
Complex,
ComplexPolar,
ComplexCartesian,
Constant,
Function,
Vector,
List,
Set,
Matrix,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct Ci {
pub r#type: Option<Type>,
pub content: Box<MathExpression>,
pub func_of: Option<Vec<Ci>>,
pub notation: Option<VectorNotation>,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub enum VectorNotation {
Bold,
Arrow,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct Differential {
pub diff: Box<MathExpression>,
pub func: Box<MathExpression>,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct SummationMath {
pub op: Box<MathExpression>,
pub func: Box<MathExpression>,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct ExpMath {
pub op: Box<MathExpression>,
pub func: Box<MathExpression>,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct Integral {
pub op: Box<MathExpression>,
pub integrand: Box<MathExpression>,
pub integration_variable: Box<MathExpression>,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct HatComp {
pub op: Box<MathExpression>,
pub comp: Box<MathExpression>,
}
#[derive(
Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Hash, new, Deserialize, Serialize, JsonSchema,
)]
pub struct LaplacianComp {
pub op: Box<MathExpression>,
pub comp: Ci,
}
#[derive(
Debug,
Ord,
PartialOrd,
PartialEq,
Eq,
Clone,
Hash,
new,
Deserialize,
Serialize,
ToSchema,
JsonSchema,
)]
pub struct DownArrow {
pub sub: Option<Box<MathExpression>>,
pub sup: Option<Box<MathExpression>>,
pub comp: Box<MathExpression>,
}
#[derive(
Debug,
PartialOrd,
Ord,
PartialEq,
Eq,
Clone,
Hash,
Default,
new,
Deserialize,
Serialize,
ToSchema,
JsonSchema,
)]
pub enum MathExpression {
Mi(Mi),
Mo(Operator),
Mn(String),
Msqrt(Box<MathExpression>),
Mrow(Mrow),
Mfrac(Box<MathExpression>, Box<MathExpression>),
Msup(Box<MathExpression>, Box<MathExpression>),
Msub(Box<MathExpression>, Box<MathExpression>),
Munder(Box<MathExpression>, Box<MathExpression>),
Mover(Box<MathExpression>, Box<MathExpression>),
Msubsup(
Box<MathExpression>,
Box<MathExpression>,
Box<MathExpression>,
),
Mtext(String),
Mstyle(Vec<MathExpression>),
Mspace(String),
MoLine(String),
Ci(Ci),
Differential(Differential),
SummationMath(SummationMath),
AbsoluteSup(Box<MathExpression>, Box<MathExpression>),
Absolute(Box<MathExpression>, Box<MathExpression>),
HatComp(HatComp),
Integral(Integral),
LaplacianComp(LaplacianComp),
SurfaceIntegral(Box<MathExpression>),
DownArrow(DownArrow),
Minimize(Box<MathExpression>, Vec<MathExpression>),
ExpMath(ExpMath),
#[default]
None,
}
impl fmt::Display for MathExpression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MathExpression::Mi(Mi(identifier)) => write!(f, "{}", identifier),
MathExpression::Ci(Ci {
r#type: _,
content,
func_of: _,
notation: _,
}) => write!(f, "{}", content),
MathExpression::Mn(number) => write!(f, "{}", number),
MathExpression::Msup(base, superscript) => {
write!(f, "{base}^{{{superscript}}}")
}
MathExpression::Msub(base, subscript) => {
write!(f, "{base}_{{{subscript}}}")
}
MathExpression::Msubsup(base, subscript, superscript) => {
write!(f, "{base}_{{{subscript}}}^{{{superscript}}}")
}
MathExpression::Mo(op) => {
write!(f, "{}", op)
}
MathExpression::Mrow(Mrow(elements)) => {
for e in elements {
write!(f, "{}", e)?;
}
Ok(())
}
MathExpression::Differential(Differential { diff, func }) => {
write!(f, "{diff}")?;
write!(f, "{func}")
}
MathExpression::AbsoluteSup(base, superscript) => {
write!(f, "{:?}", base)?;
write!(f, "{superscript:?}")
}
MathExpression::Mtext(text) => write!(f, "{}", text),
MathExpression::SummationMath(SummationMath { op, func }) => {
write!(f, "{op}")?;
write!(f, "{func}")
}
MathExpression::ExpMath(ExpMath { op, func }) => {
write!(f, "{op}")?;
write!(f, "{func}")
}
MathExpression::HatComp(HatComp { op, comp }) => {
write!(f, "{op}")?;
write!(f, "{comp}")
}
MathExpression::Integral(Integral {
op,
integrand,
integration_variable,
}) => {
write!(f, "{op}")?;
write!(f, "{integrand}")?;
write!(f, "{integration_variable}")
}
MathExpression::LaplacianComp(LaplacianComp { op, comp }) => {
write!(f, "{op}(")?;
write!(f, "{comp})")
}
MathExpression::SurfaceIntegral(row) => {
write!(f, "{row})")
}
MathExpression::DownArrow(DownArrow { sub, sup, comp }) => match (sub, sup) {
(Some(low), Some(up)) => write!(f, "{comp}↓_{{{low}}}^{{{up}}}"),
(Some(low), None) => write!(f, "{comp}↓_{{{low}}}"),
(None, Some(up)) => write!(f, "{comp}↓^{{{up}}}"),
(None, None) => write!(f, "{comp}↓"),
},
MathExpression::Minimize(op, row) => {
for e in row {
write!(f, "{}", e)?;
}
Ok(())
}
expression => write!(f, "{expression:?}"),
}
}
}
impl fmt::Display for Ci {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.content)
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Math {
pub content: Vec<MathExpression>,
}