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}