-module(caffeine_query_language@printer). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_query_language/printer.gleam"). -export([operator_to_string/1, exp_to_string/1, strip_outer_parens/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/caffeine_query_language/printer.gleam", 58). ?DOC(false). -spec operator_to_string(caffeine_query_language@ast:operator()) -> binary(). operator_to_string(Operator) -> case Operator of add -> <<"+"/utf8>>; sub -> <<"-"/utf8>>; mul -> <<"*"/utf8>>; 'div' -> <<"/"/utf8>> end. -file("src/caffeine_query_language/printer.gleam", 97). -spec all_divisions(caffeine_query_language@ast:exp(any())) -> boolean(). all_divisions(Exp) -> case Exp of {primary, _} -> true; {operator_expr, Left, Right, 'div'} -> all_divisions(Left) andalso all_divisions(Right); _ -> false end. -file("src/caffeine_query_language/printer.gleam", 88). -spec get_leftmost_word(caffeine_query_language@ast:exp(any())) -> gleam@option:option(binary()). get_leftmost_word(Exp) -> case Exp of {primary, {primary_word, {word, W}}} -> {some, W}; {primary, {primary_exp, Inner_exp}} -> get_leftmost_word(Inner_exp); {time_slice_expr, _} -> none; {operator_expr, Left, _, _} -> get_leftmost_word(Left) end. -file("src/caffeine_query_language/printer.gleam", 76). -spec is_path_expression(caffeine_query_language@ast:exp(any())) -> boolean(). is_path_expression(Exp) -> case get_leftmost_word(Exp) of {some, W} -> case gleam_stdlib:string_ends_with(W, <<":"/utf8>>) of true -> all_divisions(Exp); false -> false end; none -> false end. -file("src/caffeine_query_language/printer.gleam", 67). -spec float_to_string(float()) -> binary(). float_to_string(F) -> Truncated = erlang:trunc(F), Is_whole = erlang:float(Truncated) =:= F, case Is_whole of true -> erlang:integer_to_binary(Truncated); false -> gleam_stdlib:float_to_string(F) end. -file("src/caffeine_query_language/printer.gleam", 47). ?DOC(" Converts a CQL comparator to its string representation.\n"). -spec comparator_to_string(caffeine_query_language@ast: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/printer.gleam", 106). -spec exp_to_string_no_spaces(caffeine_query_language@ast:exp(any())) -> binary(). exp_to_string_no_spaces(Exp) -> case Exp of {primary, {primary_word, {word, W}}} -> W; {operator_expr, Left, Right, 'div'} -> <<<<(exp_to_string_no_spaces(Left))/binary, "/"/utf8>>/binary, (exp_to_string_no_spaces(Right))/binary>>; _ -> exp_to_string(Exp) end. -file("src/caffeine_query_language/printer.gleam", 143). -spec primary_to_string( caffeine_query_language@ast:primary(any()), gleam@option:option(caffeine_query_language@ast:operator()) ) -> binary(). primary_to_string(Primary, _) -> case Primary of {primary_word, Word} -> erlang:element(2, Word); {primary_exp, Exp} -> <<<<"("/utf8, (exp_to_string(Exp))/binary>>/binary, ")"/utf8>> end. -file("src/caffeine_query_language/printer.gleam", 115). -spec exp_to_string_with_context( caffeine_query_language@ast:exp(any()), gleam@option:option(caffeine_query_language@ast:operator()), boolean() ) -> binary(). exp_to_string_with_context(Exp, Parent_op, _) -> case Exp of {primary, Primary} -> primary_to_string(Primary, Parent_op); {time_slice_expr, _} -> exp_to_string(Exp); {operator_expr, Numerator, Denominator, Operator} -> case {Operator, is_path_expression(Exp)} of {'div', true} -> exp_to_string_no_spaces(Exp); {_, _} -> Left = exp_to_string_with_context( Numerator, {some, Operator}, true ), Right = exp_to_string_with_context( Denominator, {some, Operator}, false ), Op = operator_to_string(Operator), <<<<<<<>/binary, Op/binary>>/binary, " "/utf8>>/binary, Right/binary>> end end. -file("src/caffeine_query_language/printer.gleam", 11). ?DOC(false). -spec exp_to_string(caffeine_query_language@ast:exp(any())) -> binary(). exp_to_string(Exp) -> case Exp of {primary, Primary} -> primary_to_string(Primary, none); {time_slice_expr, Spec} -> <<<<<<<<<<<<<<<<"time_slice("/utf8, (erlang:element(2, Spec))/binary>>/binary, " "/utf8>>/binary, (comparator_to_string( erlang:element(3, Spec) ))/binary>>/binary, " "/utf8>>/binary, (float_to_string(erlang:element(4, Spec)))/binary>>/binary, " per "/utf8>>/binary, (float_to_string(erlang:element(5, Spec)))/binary>>/binary, "s)"/utf8>>; {operator_expr, Numerator, Denominator, Operator} -> case {Operator, is_path_expression(Exp)} of {'div', true} -> exp_to_string_no_spaces(Exp); {_, _} -> Left = exp_to_string_with_context( Numerator, {some, Operator}, true ), Right = exp_to_string_with_context( Denominator, {some, Operator}, false ), Op = operator_to_string(Operator), <<<<<<<>/binary, Op/binary>>/binary, " "/utf8>>/binary, Right/binary>> end end. -file("src/caffeine_query_language/printer.gleam", 172). -spec is_balanced(binary(), integer()) -> boolean(). is_balanced(S, Depth) -> case gleam_stdlib:string_pop_grapheme(S) of {error, _} -> Depth =:= 0; {ok, {<<"("/utf8>>, Rest}} -> is_balanced(Rest, Depth + 1); {ok, {<<")"/utf8>>, Rest@1}} -> case Depth of 0 -> false; _ -> is_balanced(Rest@1, Depth - 1) end; {ok, {_, Rest@2}} -> is_balanced(Rest@2, Depth) end. -file("src/caffeine_query_language/printer.gleam", 158). ?DOC(false). -spec strip_outer_parens(binary()) -> binary(). strip_outer_parens(S) -> Trimmed = gleam@string:trim(S), case gleam_stdlib:string_starts_with(Trimmed, <<"("/utf8>>) andalso gleam_stdlib:string_ends_with( Trimmed, <<")"/utf8>> ) of true -> Inner = gleam@string:slice(Trimmed, 1, string:length(Trimmed) - 2), case is_balanced(Inner, 0) of true -> Inner; false -> Trimmed end; false -> Trimmed end.