frequenz_microgrid_component_graph/graph/formulas/
formula.rs1use super::expr::Expr;
7
8pub trait Formula {
10 fn coalesce(self, other: Self) -> Self;
11 fn min(self, other: Self) -> Self;
12 fn max(self, other: Self) -> Self;
13}
14
15impl<T> Formula for T
18where
19 T: From<Expr>,
20 Expr: From<T>,
21{
22 fn coalesce(self, other: Self) -> Self {
23 Expr::coalesce(self.into(), other.into()).into()
24 }
25
26 fn min(self, other: Self) -> Self {
27 Expr::min(self.into(), other.into()).into()
28 }
29
30 fn max(self, other: Self) -> Self {
31 Expr::max(self.into(), other.into()).into()
32 }
33}
34
35#[derive(Debug, Clone, PartialEq)]
45pub struct AggregationFormula {
46 pub(crate) expr: Expr,
47}
48
49impl From<Expr> for AggregationFormula {
50 fn from(expr: Expr) -> Self {
51 AggregationFormula { expr }
52 }
53}
54
55impl From<AggregationFormula> for Expr {
56 fn from(formula: AggregationFormula) -> Self {
57 formula.expr
58 }
59}
60
61impl AggregationFormula {
62 pub(crate) fn new(expr: Expr) -> Self {
63 AggregationFormula { expr }
64 }
65}
66
67impl std::ops::Add for AggregationFormula {
68 type Output = Self;
69
70 fn add(self, rhs: Self) -> Self::Output {
71 AggregationFormula {
72 expr: self.expr + rhs.expr,
73 }
74 }
75}
76
77impl std::ops::Sub for AggregationFormula {
78 type Output = Self;
79
80 fn sub(self, rhs: Self) -> Self::Output {
81 AggregationFormula {
82 expr: self.expr - rhs.expr,
83 }
84 }
85}
86
87impl std::fmt::Display for AggregationFormula {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 self.expr.fmt(f)
90 }
91}
92
93impl From<AggregationFormula> for String {
94 fn from(formula: AggregationFormula) -> Self {
95 formula.expr.to_string()
96 }
97}
98
99#[derive(Debug, Clone, PartialEq)]
104pub struct CoalesceFormula {
105 expr: Expr,
106}
107
108impl From<Expr> for CoalesceFormula {
109 fn from(expr: Expr) -> Self {
110 CoalesceFormula { expr }
111 }
112}
113
114impl From<CoalesceFormula> for Expr {
115 fn from(formula: CoalesceFormula) -> Self {
116 formula.expr
117 }
118}
119
120impl CoalesceFormula {
121 pub(crate) fn new(expr: Expr) -> Self {
122 CoalesceFormula { expr }
123 }
124}
125
126impl std::fmt::Display for CoalesceFormula {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 self.expr.fmt(f)
129 }
130}
131
132impl From<CoalesceFormula> for String {
133 fn from(formula: CoalesceFormula) -> Self {
134 formula.expr.to_string()
135 }
136}
137
138#[test]
139fn test_aggregation_formula_arith() {
140 let formula1 = AggregationFormula::new(Expr::component(1));
141 let formula2 = AggregationFormula::new(Expr::component(2));
142
143 let result = formula1.clone() + formula2.clone();
144 assert_eq!(result.to_string(), "#1 + #2");
145
146 let result = formula1 - formula2;
147 assert_eq!(result.to_string(), "#1 - #2");
148}
149
150#[test]
151fn test_formula_trait() {
152 let formula1 = AggregationFormula::new(Expr::component(1));
153 let formula2 = AggregationFormula::new(Expr::component(2));
154
155 let coalesce_result = formula1.clone().coalesce(formula2.clone());
156 assert_eq!(coalesce_result.to_string(), "COALESCE(#1, #2)");
157
158 let min_result = formula1.clone().min(formula2.clone());
159 assert_eq!(min_result.to_string(), "MIN(#1, #2)");
160
161 let max_result = formula1.max(formula2);
162 assert_eq!(max_result.to_string(), "MAX(#1, #2)");
163
164 let formula3 = CoalesceFormula::new(Expr::component(3));
165 let formula4 = CoalesceFormula::new(Expr::component(4));
166
167 let coalesce_result = formula3.clone().coalesce(formula4.clone());
168 assert_eq!(coalesce_result.to_string(), "COALESCE(#3, #4)");
169
170 let min_result = formula3.clone().min(formula4.clone());
171 assert_eq!(min_result.to_string(), "MIN(#3, #4)");
172
173 let max_result = formula3.max(formula4);
174 assert_eq!(max_result.to_string(), "MAX(#3, #4)");
175}