26
26
#include < fmt/format.h>
27
27
28
28
#include < numeric>
29
+ #include < stdexcept>
29
30
#include < unordered_set>
30
31
31
32
using Log = metricq::logger::nitro::Log;
@@ -50,45 +51,102 @@ Combinator::~Combinator()
50
51
{
51
52
}
52
53
53
- std::string displayExpression (const nlohmann::json& expression) {
54
+ std::string handleBasicExpression (const nlohmann::json& expression)
55
+ {
56
+ if (expression.is_number ())
57
+ {
58
+ auto value = expression.get <double >();
59
+ return (value == static_cast <int >(value)) ? std::to_string (static_cast <int >(value)) :
60
+ std::to_string (value);
61
+ }
62
+
63
+ if (expression.is_string ())
64
+ {
65
+ return expression.get <std::string>();
66
+ }
67
+
68
+ throw std::runtime_error (" Expression is not a basic type (number or string)!" );
69
+ }
70
+
71
+ std::string handleOperatorExpression (const std::string& operation, const std::string& leftStr,
72
+ const std::string& rightStr)
73
+ {
54
74
static const std::unordered_set<std::string> validOperators = { " +" , " -" , " *" , " /" };
55
75
56
- // Check if the expression is a number and return it as a string
57
- if (expression.is_number ()) {
58
- double value = expression.get <double >();
59
- return (value == static_cast <int >(value)) ? std::to_string (static_cast <int >(value)) : std::to_string (value);
76
+ if (validOperators.find (operation) == validOperators.end ())
77
+ {
78
+ throw std::runtime_error (" Invalid operator: " + operation);
60
79
}
61
80
62
- if (expression.is_object () && expression.contains (" operation" )) {
63
- std::string operation = expression.value (" operation" , " " );
81
+ return operation + (leftStr.empty () ? " " : " " + leftStr) +
82
+ (rightStr.empty () ? " " : " " + rightStr);
83
+ }
64
84
65
- // Validate if the operation is supported
66
- if (validOperators. find (operation) == validOperators. end ()) {
67
- return operation;
68
- }
85
+ std::string handleAggregateExpression ( const std::string& operation,
86
+ const std::vector<std::string>& inputs)
87
+ {
88
+ static const std::unordered_set<std::string> validAggregates = { " sum " , " min " , " max " };
69
89
70
- // Helper lambda to process operands
71
- auto processOperand = [&](const std::string& key) -> std::string {
72
- if (expression.contains (key)) {
73
- const auto & operand = expression[key];
74
- if (operand.is_string ()) return operand.get <std::string>();
75
- if (operand.is_number ()) return std::to_string (operand.get <int >());
76
- return displayExpression (operand);
77
- }
78
- return " " ;
79
- };
90
+ if (validAggregates.find (operation) == validAggregates.end ())
91
+ {
92
+ throw std::runtime_error (" Invalid aggregate operation: " + operation);
93
+ }
80
94
81
- std::string leftStr = processOperand ( " left " );
82
- std::string rightStr = processOperand ( " right " );
83
- return operation + (leftStr. empty () ? " " : " " + leftStr) + (rightStr. empty () ? " " : " " + rightStr );
95
+ if (inputs. empty ())
96
+ {
97
+ throw std::logic_error ( " Aggregate operation missing inputs! " );
84
98
}
85
99
86
- // If the expression is a string, return it directly
87
- if (expression.is_string ()) {
88
- return expression.get <std::string>();
100
+ auto input = std::accumulate (std::next (inputs.begin ()), inputs.end (), inputs[0 ],
101
+ [](std::string a, const std::string& b) { return a + " , " + b; });
102
+
103
+ return operation + " : [" + input + " ]" ;
104
+ }
105
+
106
+ std::string displayExpression (const nlohmann::json& expression)
107
+ {
108
+ if (expression.is_number () || expression.is_string ())
109
+ {
110
+ return handleBasicExpression (expression);
111
+ }
112
+
113
+ if (!expression.is_object () || !expression.contains (" operation" ))
114
+ {
115
+ throw std::runtime_error (" Unknown expression format!" );
116
+ }
117
+
118
+ std::string operation = expression.value (" operation" , " " );
119
+
120
+ if (operation == " throttle" )
121
+ {
122
+ return operation;
123
+ }
124
+
125
+ if (expression.contains (" left" ) || expression.contains (" right" ))
126
+ {
127
+ std::string leftStr =
128
+ expression.contains (" left" ) ? displayExpression (expression[" left" ]) : " " ;
129
+ std::string rightStr =
130
+ expression.contains (" right" ) ? displayExpression (expression[" right" ]) : " " ;
131
+ return handleOperatorExpression (operation, leftStr, rightStr);
132
+ }
133
+
134
+ if (expression.contains (" inputs" ))
135
+ {
136
+ if (!expression[" inputs" ].is_array ())
137
+ {
138
+ throw std::logic_error (" Inputs must be an array!" );
139
+ }
140
+
141
+ std::vector<std::string> inputStrings;
142
+ for (const auto & input : expression[" inputs" ])
143
+ {
144
+ inputStrings.push_back (displayExpression (input));
145
+ }
146
+ return handleAggregateExpression (operation, inputStrings);
89
147
}
90
148
91
- return " Unknown expression format " ;
149
+ throw std::runtime_error ( " Unsupported operation type: " + operation) ;
92
150
}
93
151
94
152
void Combinator::on_transformer_config (const metricq::json& config)
0 commit comments