2626#include < fmt/format.h>
2727
2828#include < numeric>
29+ #include < stdexcept>
2930#include < unordered_set>
3031
3132using Log = metricq::logger::nitro::Log;
@@ -50,45 +51,102 @@ Combinator::~Combinator()
5051{
5152}
5253
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+ {
5474 static const std::unordered_set<std::string> validOperators = { " +" , " -" , " *" , " /" };
5575
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);
6079 }
6180
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+ }
6484
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 " };
6989
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+ }
8094
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! " );
8498 }
8599
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);
89147 }
90148
91- return " Unknown expression format " ;
149+ throw std::runtime_error ( " Unsupported operation type: " + operation) ;
92150}
93151
94152void Combinator::on_transformer_config (const metricq::json& config)
0 commit comments