-module(caffeine_query_language@resolver). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_query_language/resolver.gleam"). -export([comparator_to_string/1, resolve_primitives/1]). -export_type([primitives/0, comparator/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type primitives() :: {good_over_total, caffeine_query_language@parser:exp(), caffeine_query_language@parser:exp()} | {time_slice, comparator(), integer(), float(), binary()}. -type comparator() :: less_than | less_than_or_equal_to | greater_than | greater_than_or_equal_to. -file("src/caffeine_query_language/resolver.gleam", 29). -spec comparator_to_string(comparator()) -> binary(). comparator_to_string(Comparator) -> case Comparator of less_than -> <<"\"<\""/utf8>>; less_than_or_equal_to -> <<"\"<=\""/utf8>>; greater_than -> <<"\">\""/utf8>>; greater_than_or_equal_to -> <<"\">=\""/utf8>> end. -file("src/caffeine_query_language/resolver.gleam", 39). ?DOC(" Converts a parser Comparator to a resolver Comparator.\n"). -spec convert_comparator(caffeine_query_language@parser:comparator()) -> comparator(). convert_comparator(Comp) -> case Comp of less_than -> less_than; less_than_or_equal_to -> less_than_or_equal_to; greater_than -> greater_than; greater_than_or_equal_to -> greater_than_or_equal_to end. -file("src/caffeine_query_language/resolver.gleam", 83). ?DOC(" Checks if an expression contains a time_slice expression anywhere.\n"). -spec contains_time_slice(caffeine_query_language@parser:exp()) -> boolean(). contains_time_slice(Exp) -> case Exp of {time_slice_expr, _} -> true; {operator_expr, Left, Right, _} -> contains_time_slice(Left) orelse contains_time_slice(Right); {primary, {primary_exp, Inner}} -> contains_time_slice(Inner); {primary, {primary_word, _}} -> false end. -file("src/caffeine_query_language/resolver.gleam", 51). ?DOC( " Resolves a parsed CQL expression into a primitive type.\n" " Supports GoodOverTotal (division at the top level) and TimeSlice.\n" " Returns an error if the expression doesn't match a known primitive pattern.\n" ). -spec resolve_primitives(caffeine_query_language@parser:exp_container()) -> {ok, primitives()} | {error, caffeine_lang@common@errors:compilation_error()}. resolve_primitives(Exp_container) -> case Exp_container of {exp_container, Exp} -> case Exp of {operator_expr, Left, Right, 'div'} -> case contains_time_slice(Left) orelse contains_time_slice( Right ) of true -> {error, {c_q_l_resolver_error, <<"time_slice cannot be used as an operand. It must be the entire expression."/utf8>>}}; false -> {ok, {good_over_total, Left, Right}} end; {time_slice_expr, Spec} -> {ok, {time_slice, convert_comparator(erlang:element(3, Spec)), erlang:trunc(erlang:element(5, Spec)), erlang:element(4, Spec), erlang:element(2, Spec)}}; _ -> {error, {c_q_l_resolver_error, <<"Invalid expression. Expected a top level division operator or time_slice."/utf8>>}} end end.