diff --git a/src/combinator.cpp b/src/combinator.cpp index c0aa5d6..40e594e 100644 --- a/src/combinator.cpp +++ b/src/combinator.cpp @@ -26,6 +26,7 @@ #include #include +#include using Log = metricq::logger::nitro::Log; @@ -49,6 +50,69 @@ Combinator::~Combinator() { } +std::string toPrefixNotation(const nlohmann::json& expression, const std::unordered_set& validOperators) { + // Check if the expression is a simple number and return it as a string + if (expression.is_number()) { + double value = expression.get(); + return (value == static_cast(value)) ? std::to_string(static_cast(value)) : std::to_string(value); + } + + // check if operation is valid + std::string operation = expression.value("operation", ""); + if (validOperators.find(operation) == validOperators.end()) { + return operation; // Unsupported operation, return as is + } + + auto processOperand = [&](const std::string& key) -> std::string { + if (expression.contains(key)) { + const auto& operand = expression[key]; + if (operand.is_string()) return operand.get(); + if (operand.is_number()) return std::to_string(operand.get()); + return toPrefixNotation(operand, validOperators); // Recursively handle nested objects + } + return ""; + }; + + // Build the prefix notation "operation left right" + std::string leftStr = processOperand("left"); + std::string rightStr = processOperand("right"); + return operation + (leftStr.empty() ? "" : " " + leftStr) + (rightStr.empty() ? "" : " " + rightStr); +} + +std::string displayExpression(const nlohmann::json& expression) +{ + static const std::unordered_set validOperators = { "+", "-", "*", "/" }; + + if (expression.is_object() && expression.contains("operation")) + { + std::string operation = expression.value("operation", ""); + + // Check if operation is a valid operator at the top level + if (validOperators.find(operation) != validOperators.end()) + { + return toPrefixNotation(expression, validOperators); + } + else + { + return operation; // Return the operation as a string if unsupported + } + } + + if (expression.is_string()) + { + return expression.get(); + } + + if (expression.is_number()) + { + return (expression == static_cast(expression)) ? + std::to_string(static_cast(expression)) : + std::to_string(static_cast(expression)); + } + + return "Unknown expression format"; +} + void Combinator::on_transformer_config(const metricq::json& config) { input_metrics.clear(); @@ -93,6 +157,8 @@ void Combinator::on_transformer_config(const metricq::json& config) // Register the combined metric as a new source metric auto& metric = (*this)[combined_name]; + metric.metadata["displayExpression"] = displayExpression(combined_expression); + if (combined_config.count("chunk_size")) { auto chunk_size = combined_config["chunk_size"].get();