Packages
caffeine_lang
0.0.24
6.3.1
6.3.0
6.2.2
6.2.1
6.2.0
6.1.2
6.1.1
6.1.0
6.0.0
5.6.0
5.5.0
5.4.4
5.4.3
5.4.2
5.4.1
5.4.0
5.3.0
5.2.0
5.1.1
5.1.0
5.0.12
5.0.11
5.0.10
5.0.8
5.0.7
5.0.6
5.0.5
5.0.4
5.0.1
5.0.0
4.10.0
4.9.0
4.8.3
4.8.2
4.8.1
4.8.0
4.7.9
4.7.8
4.7.7
4.7.6
4.7.5
4.6.7
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.7
4.3.6
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.0.2
1.0.1
0.1.0
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.2
0.0.1
A compiler for generating reliability artifacts from service expectation definitions.
Current section
Files
Jump to
Current section
Files
src/deps/cql/generator.gleam
import deps/cql/parser.{
type Exp, type Operator, type Primary, PrimaryExp, PrimaryWord,
}
import deps/cql/resolver.{type Primitives, GoodOverTotal}
import gleam/option.{type Option, None, Some}
import gleam/string
// Datadog
pub fn generate_datadog_query(primitive: Primitives) -> String {
case primitive {
GoodOverTotal(numerator, denominator) -> {
"query {\n"
<> " numerator = \""
<> numerator_exp_to_datadog_query(numerator)
<> "\"\n"
<> " denominator = \""
<> denominator_exp_to_datadog_query(denominator)
<> "\"\n"
<> " }\n"
}
}
}
fn numerator_exp_to_datadog_query(exp: Exp) -> String {
// Unwrap outer PrimaryExp at top level only
case exp {
parser.Primary(PrimaryExp(exp:)) -> exp_to_string(exp)
_ -> exp_to_string(exp)
}
}
fn denominator_exp_to_datadog_query(exp: Exp) -> String {
// Unwrap outer PrimaryExp at top level only
case exp {
parser.Primary(PrimaryExp(exp:)) -> exp_to_string(exp)
_ -> exp_to_string(exp)
}
}
pub fn exp_to_string(exp: Exp) -> String {
case exp {
parser.Primary(primary:) -> primary_to_string(primary, None)
parser.OperatorExpr(numerator:, denominator:, operator:) -> {
// Check if this entire expression tree is a path (all divisions with path-like components)
case operator, is_path_expression(exp) {
parser.Div, True -> {
// This is a path, render without spaces
exp_to_string_no_spaces(exp)
}
_, _ -> {
// Normal expression with spaces
let left = exp_to_string_with_context(numerator, Some(operator), True)
let right =
exp_to_string_with_context(denominator, Some(operator), False)
let op = operator_to_datadog_query(operator)
left <> " " <> op <> " " <> right
}
}
}
}
}
// Check if an expression is a path (all divisions with simple word components)
// A path expression starts with a field name ending in colon (like http.url_details.path:)
fn is_path_expression(exp: Exp) -> Bool {
// First check if the leftmost component is a field name (ends with :)
case get_leftmost_word(exp) {
Some(w) -> {
case string.ends_with(w, ":") {
True -> all_divisions(exp)
False -> False
}
}
None -> False
}
}
// Get the leftmost word in an expression tree
fn get_leftmost_word(exp: Exp) -> Option(String) {
case exp {
parser.Primary(parser.PrimaryWord(parser.Word(w))) -> Some(w)
parser.Primary(parser.PrimaryExp(inner_exp)) -> get_leftmost_word(inner_exp)
parser.OperatorExpr(left, _, _) -> get_leftmost_word(left)
}
}
// Check if an expression is all divisions (no other operators)
fn all_divisions(exp: Exp) -> Bool {
case exp {
parser.Primary(_) -> True
parser.OperatorExpr(left, right, parser.Div) ->
all_divisions(left) && all_divisions(right)
_ -> False
}
}
// Convert expression to string without spaces (for paths)
fn exp_to_string_no_spaces(exp: Exp) -> String {
case exp {
parser.Primary(parser.PrimaryWord(parser.Word(w))) -> w
parser.OperatorExpr(left, right, parser.Div) ->
exp_to_string_no_spaces(left) <> "/" <> exp_to_string_no_spaces(right)
_ -> exp_to_string(exp)
}
}
fn exp_to_string_with_context(
exp: Exp,
parent_op: Option(Operator),
_is_left: Bool,
) -> String {
case exp {
parser.Primary(primary:) -> primary_to_string(primary, parent_op)
parser.OperatorExpr(numerator:, denominator:, operator:) -> {
// Check if this is a path expression to avoid adding spaces
// This is important when the division is part of a larger expression (e.g., with AND)
case operator, is_path_expression(exp) {
parser.Div, True -> exp_to_string_no_spaces(exp)
_, _ -> {
// Not a path, render with spaces
let left = exp_to_string_with_context(numerator, Some(operator), True)
let right =
exp_to_string_with_context(denominator, Some(operator), False)
let op = operator_to_datadog_query(operator)
left <> " " <> op <> " " <> right
}
}
}
}
}
fn primary_to_string(primary: Primary, _parent_op: Option(Operator)) -> String {
case primary {
PrimaryWord(word:) -> word.value
PrimaryExp(exp:) -> {
// Always preserve explicit parentheses from the original input
"(" <> exp_to_string(exp) <> ")"
}
}
}
pub fn operator_to_datadog_query(operator: parser.Operator) -> String {
case operator {
parser.Add -> "+"
parser.Sub -> "-"
parser.Mul -> "*"
parser.Div -> "/"
}
}