symrs/expr/
symbol.rs

1use serde::{Deserialize, Serialize};
2
3use super::*;
4#[derive(Clone, Debug, Hash, PartialEq, Eq, JsonSchema, Deserialize, Serialize)]
5#[serde(from = "String", into = "String")]
6pub struct Symbol {
7    pub name: String,
8}
9
10impl Symbol {
11    pub fn new(name: &str) -> Symbol {
12        Self::new_v2(name.to_string())
13    }
14
15    pub fn new_v2(name: String) -> Symbol {
16        Symbol {
17            name: (match name.as_str() {
18                "nabla" => "∇".into(),
19                "laplacian" => "Δ".into(),
20                "theta" => "θ".into(),
21                _ => name,
22            }),
23        }
24    }
25
26    pub fn new_box(name: &str) -> Box<dyn Expr> {
27        Box::new(Symbol::new(name))
28    }
29}
30
31impl std::fmt::Display for Symbol {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        write!(f, "{}", self.name)
34    }
35}
36
37impl Expr for Symbol {
38    fn known_expr(&self) -> KnownExpr {
39        KnownExpr::Symbol(self)
40    }
41    fn get_ref<'a>(&'a self) -> &'a dyn Expr {
42        self as &dyn Expr
43    }
44    fn for_each_arg(&self, f: &mut dyn FnMut(&dyn Arg) -> ()) {
45        f(&self.name);
46    }
47
48    fn from_args(&self, args: Vec<Box<dyn Arg>>) -> Box<dyn Expr> {
49        let name = (&*args[0]) as &dyn Any;
50
51        let name = name.downcast_ref::<String>().unwrap();
52        Box::new(Symbol { name: name.clone() })
53    }
54
55    fn clone_box(&self) -> Box<dyn Expr> {
56        Box::new(self.clone())
57    }
58
59    fn str(&self) -> String {
60        self.name.clone()
61    }
62    fn to_cpp(&self) -> String {
63        match self.name.as_str() {
64            "M^n" => "mass_mat".to_string(),
65            "A^n" => "laplace_mat".to_string(),
66            "k" => "time_step".to_string(),
67            _ => self
68                .name
69                .replace("^n-1", "_prev")
70                .replace("^n", "")
71                .to_lowercase(),
72        }
73    }
74}
75
76impl<E: Expr> std::ops::Add<&E> for &Symbol {
77    type Output = Box<dyn Expr>;
78
79    fn add(self, rhs: &E) -> Self::Output {
80        self.get_ref() + rhs.get_ref()
81    }
82}
83
84impl<E: Expr> std::ops::Mul<&E> for &Symbol {
85    type Output = Box<dyn Expr>;
86
87    fn mul(self, rhs: &E) -> Self::Output {
88        self.get_ref() * rhs.get_ref()
89    }
90}
91
92impl<E: Expr> std::ops::Div<&E> for &Symbol {
93    type Output = Box<dyn Expr>;
94
95    fn div(self, rhs: &E) -> Self::Output {
96        self.get_ref() / rhs.get_ref()
97    }
98}
99
100impl From<String> for Symbol {
101    fn from(value: String) -> Self {
102        Self::new_v2(value)
103    }
104}
105
106impl Into<String> for Symbol {
107    fn into(self) -> String {
108        format!("{self}")
109    }
110}