Skip to main content

solidrs/
var.rs

1use crate::calc::Calc;
2
3#[macro_export]
4macro_rules! var {
5    ($var:ident,$val:literal) => {
6        const $var: Var = Var::new(stringify!($var), stringify!($val), false);
7    };
8    ($var:ident,$val:literal,$comment:literal) => {
9        #[doc = $comment]
10        const $var: Var = Var::commented(stringify!($var), $comment, stringify!($val), false);
11    };
12}
13#[macro_export]
14macro_rules! calc {
15    ($var:ident,$val:expr) => {
16        const $var: Var = Var::new(stringify!($var), stringify!($val), true);
17    };
18    ($var:ident,$val:expr,$comment:literal) => {
19        #[doc = $comment]
20        const $var: Var = Var::commented(stringify!($var), $comment, stringify!($val), true);
21    };
22}
23
24pub trait Arg: Sized {
25    fn val(self) -> Val;
26}
27
28impl Arg for Var {
29    fn val(self) -> Val {
30        Val::Var(self)
31    }
32}
33impl Arg for Val {
34    fn val(self) -> Val {
35        self
36    }
37}
38impl Arg for Calc {
39    fn val(self) -> Val {
40        Val::Calc(self)
41    }
42}
43impl Arg for f32 {
44    fn val(self) -> Val {
45        Val::Val(self)
46    }
47}
48impl Arg for i32 {
49    #[allow(clippy::cast_precision_loss)]
50    fn val(self) -> Val {
51        Val::Val(self as f32)
52    }
53}
54#[derive(Clone, Copy)]
55pub struct Var {
56    name: &'static str,
57    comment: &'static str,
58    val: &'static str,
59    calc: bool,
60}
61impl Var {
62    #[must_use]
63    pub const fn new(name: &'static str, val: &'static str, calc: bool) -> Var {
64        Self {
65            name,
66            comment: "",
67            val,
68            calc,
69        }
70    }
71    #[must_use]
72    pub const fn commented(
73        name: &'static str,
74        comment: &'static str,
75        val: &'static str,
76        calc: bool,
77    ) -> Var {
78        Self {
79            name,
80            comment,
81            val,
82            calc,
83        }
84    }
85    pub(crate) fn get_comment(&self) -> &'static str {
86        self.comment
87    }
88    pub(crate) fn get_name(&self) -> &'static str {
89        self.name
90    }
91    pub(crate) fn get_val(&self) -> &'static str {
92        self.val
93    }
94
95    pub(crate) fn is_clac(&self) -> bool {
96        self.calc
97    }
98}
99
100#[derive(Clone)]
101pub enum Val {
102    Val(f32),
103    Var(Var),
104    Calc(Calc),
105}
106impl std::fmt::Display for Val {
107    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108        match self {
109            Val::Val(val) => f.write_str(val.to_string().as_str()),
110            Val::Var(var) => f.write_str(var.name),
111            Val::Calc(calc) => calc.fmt(f),
112        }
113    }
114}
115
116impl std::ops::Neg for Val {
117    type Output = Calc;
118
119    fn neg(self) -> Self::Output {
120        Calc::neg(self)
121    }
122}
123impl std::ops::Neg for Var {
124    type Output = Calc;
125
126    fn neg(self) -> Self::Output {
127        Calc::neg(Val::Var(self))
128    }
129}
130
131macro_rules! impl_op {
132    ($op:ident,$func:ident,$t:ty) => {
133        impl<RHS: Arg> std::ops::$op<RHS> for $t {
134            type Output = Calc;
135
136            fn $func(self, rhs: RHS) -> Self::Output {
137                Calc::$func(self.val(), rhs.val())
138            }
139        }
140    };
141}
142
143impl_op!(Add, add, Val);
144impl_op!(Sub, sub, Val);
145impl_op!(Mul, mul, Val);
146impl_op!(Div, div, Val);
147
148impl_op!(Add, add, Calc);
149impl_op!(Sub, sub, Calc);
150impl_op!(Mul, mul, Calc);
151impl_op!(Div, div, Calc);
152
153impl_op!(Add, add, Var);
154impl_op!(Sub, sub, Var);
155impl_op!(Mul, mul, Var);
156impl_op!(Div, div, Var);