Packages
caffeine_lang
5.4.4
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/caffeine_query_language/resolver.gleam
import caffeine_lang/errors.{type CompilationError}
import caffeine_query_language/ast.{type Comparator, type CqlParsed, type Exp}
import gleam/bool
import gleam/float
/// Supported primitive query types that can be resolved from CQL expressions.
/// Each primitive represents a specific SLO calculation pattern.
pub type Primitives {
/// Good over total requires a top level division operator.
/// Represents an SLO where the numerator is the "good" events
/// and the denominator is the "total" events.
GoodOverTotal(numerator: Exp(CqlParsed), denominator: Exp(CqlParsed))
TimeSlice(
comparator: Comparator,
interval_in_seconds: Int,
threshold: Float,
query: String,
)
}
/// Resolves a parsed CQL expression into a primitive type.
/// Supports GoodOverTotal (division at the top level) and TimeSlice.
/// Returns an error if the expression doesn't match a known primitive pattern.
@internal
pub fn resolve_primitives(
exp: Exp(CqlParsed),
) -> Result(Primitives, CompilationError) {
case exp {
ast.OperatorExpr(left, right, ast.Div) -> {
// Check that neither operand contains a time_slice expression
use <- bool.guard(
when: contains_time_slice(left) || contains_time_slice(right),
return: Error(errors.cql_resolver_error(
msg: "time_slice cannot be used as an operand. It must be the entire expression.",
)),
)
Ok(GoodOverTotal(left, right))
}
ast.TimeSliceExpr(spec) ->
Ok(TimeSlice(
comparator: spec.comparator,
interval_in_seconds: float.truncate(spec.interval_seconds),
threshold: spec.threshold,
query: spec.query,
))
_ ->
Error(errors.cql_resolver_error(
msg: "Invalid expression. Expected a top level division operator or time_slice.",
))
}
}
/// Checks if an expression contains a time_slice expression anywhere.
fn contains_time_slice(exp: Exp(a)) -> Bool {
case exp {
ast.TimeSliceExpr(_) -> True
ast.OperatorExpr(left, right, _) ->
contains_time_slice(left) || contains_time_slice(right)
ast.Primary(ast.PrimaryExp(inner)) -> contains_time_slice(inner)
ast.Primary(ast.PrimaryWord(_)) -> False
}
}