Current section

Files

Jump to
caffeine_lang src caffeine_lang@parser@ir_builder.erl
Raw

src/caffeine_lang@parser@ir_builder.erl

-module(caffeine_lang@parser@ir_builder).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/parser/ir_builder.gleam").
-export([extract_path_prefix/1, build_all/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_lang/parser/ir_builder.gleam", 32).
?DOC(false).
-spec extract_path_prefix(binary()) -> {binary(), binary(), binary()}.
extract_path_prefix(Path) ->
case begin
_pipe = Path,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = lists:reverse(_pipe@1),
_pipe@3 = gleam@list:take(_pipe@2, 3),
_pipe@4 = lists:reverse(_pipe@3),
gleam@list:map(
_pipe@4,
fun(Segment) ->
case gleam_stdlib:string_ends_with(
Segment,
<<".caffeine"/utf8>>
) of
true ->
gleam@string:drop_end(Segment, 9);
false ->
case gleam_stdlib:string_ends_with(
Segment,
<<".json"/utf8>>
) of
true ->
gleam@string:drop_end(Segment, 5);
false ->
Segment
end
end
end
)
end of
[Org, Team, Service] ->
{Org, Team, Service};
_ ->
{<<"unknown"/utf8>>, <<"unknown"/utf8>>, <<"unknown"/utf8>>}
end.
-file("src/caffeine_lang/parser/ir_builder.gleam", 106).
?DOC(" Build value tuples from provided inputs.\n").
-spec build_provided_value_tuples(
gleam@dict:dict(binary(), gleam@dynamic:dynamic_()),
gleam@dict:dict(binary(), caffeine_lang@common@accepted_types:accepted_types())
) -> list(caffeine_lang@common@helpers:value_tuple()).
build_provided_value_tuples(Merged_inputs, Params) ->
_pipe = Merged_inputs,
_pipe@1 = maps:keys(_pipe),
gleam@list:map(
_pipe@1,
fun(Label) ->
Value@1 = case begin
_pipe@2 = Merged_inputs,
gleam_stdlib:map_get(_pipe@2, Label)
end of
{ok, Value} -> Value;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"caffeine_lang/parser/ir_builder"/utf8>>,
function => <<"build_provided_value_tuples"/utf8>>,
line => 114,
value => _assert_fail,
start => 3964,
'end' => 4019,
pattern_start => 3975,
pattern_end => 3984})
end,
Typ@1 = case begin
_pipe@3 = Params,
gleam_stdlib:map_get(_pipe@3, Label)
end of
{ok, Typ} -> Typ;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"caffeine_lang/parser/ir_builder"/utf8>>,
function => <<"build_provided_value_tuples"/utf8>>,
line => 115,
value => _assert_fail@1,
start => 4024,
'end' => 4070,
pattern_start => 4035,
pattern_end => 4042})
end,
{value_tuple, Label, Typ@1, Value@1}
end
).
-file("src/caffeine_lang/parser/ir_builder.gleam", 147).
?DOC(
" Checks if a type is optional or has a default value.\n"
" This includes:\n"
" - ModifierType(Optional(_))\n"
" - ModifierType(Defaulted(_, _))\n"
" - RefinementType(OneOf(ModifierType(Optional(_)), _))\n"
" - RefinementType(OneOf(ModifierType(Defaulted(_, _)), _))\n"
).
-spec is_optional_or_defaulted(
caffeine_lang@common@accepted_types:accepted_types()
) -> boolean().
is_optional_or_defaulted(Typ) ->
case Typ of
{modifier_type, {optional, _}} ->
true;
{modifier_type, {defaulted, _, _}} ->
true;
{refinement_type, {one_of, Inner, _}} ->
is_optional_or_defaulted(Inner);
_ ->
false
end.
-file("src/caffeine_lang/parser/ir_builder.gleam", 122).
?DOC(
" Build value tuples for Optional/Defaulted params that weren't provided.\n"
" These need to be in value_tuples so the templatizer can resolve them.\n"
).
-spec build_unprovided_optional_value_tuples(
gleam@dict:dict(binary(), gleam@dynamic:dynamic_()),
gleam@dict:dict(binary(), caffeine_lang@common@accepted_types:accepted_types())
) -> list(caffeine_lang@common@helpers:value_tuple()).
build_unprovided_optional_value_tuples(Merged_inputs, Params) ->
_pipe = Params,
_pipe@1 = maps:to_list(_pipe),
gleam@list:filter_map(
_pipe@1,
fun(Param) ->
{Label, Typ} = Param,
case gleam@dict:has_key(Merged_inputs, Label) of
true ->
{error, nil};
false ->
case is_optional_or_defaulted(Typ) of
true ->
{ok, {value_tuple, Label, Typ, gleam@dynamic:nil()}};
false ->
{error, nil}
end
end
end
).
-file("src/caffeine_lang/parser/ir_builder.gleam", 96).
?DOC(
" Build value tuples from merged inputs and params.\n"
" Includes both provided inputs and unprovided Optional/Defaulted params.\n"
).
-spec build_value_tuples(
gleam@dict:dict(binary(), gleam@dynamic:dynamic_()),
gleam@dict:dict(binary(), caffeine_lang@common@accepted_types:accepted_types())
) -> list(caffeine_lang@common@helpers:value_tuple()).
build_value_tuples(Merged_inputs, Params) ->
Provided = build_provided_value_tuples(Merged_inputs, Params),
Unprovided = build_unprovided_optional_value_tuples(Merged_inputs, Params),
lists:append(Provided, Unprovided).
-file("src/caffeine_lang/parser/ir_builder.gleam", 199).
?DOC(" Convert Result(a, String) to Result(a, Nil)\n").
-spec result_to_nil_error({ok, JCR} | {error, binary()}) -> {ok, JCR} |
{error, nil}.
result_to_nil_error(Result) ->
case Result of
{ok, Val} ->
{ok, Val};
{error, _} ->
{error, nil}
end.
-file("src/caffeine_lang/parser/ir_builder.gleam", 183).
?DOC(
" Resolves a value tuple to a string for use as a tag.\n"
" Handles Defaulted types by applying their default values when not provided.\n"
).
-spec resolve_value_for_tag(caffeine_lang@common@helpers:value_tuple()) -> {ok,
binary()} |
{error, nil}.
resolve_value_for_tag(Value_tuple) ->
Identity = fun(S) -> S end,
List_join = fun(Items) -> gleam@string:join(Items, <<","/utf8>>) end,
_pipe = caffeine_lang@common@accepted_types:resolve_to_string(
erlang:element(3, Value_tuple),
erlang:element(4, Value_tuple),
Identity,
List_join
),
result_to_nil_error(_pipe).
-file("src/caffeine_lang/parser/ir_builder.gleam", 160).
?DOC(
" Extract misc metadata from value tuples.\n"
" Filters out non-string values and specific reserved labels.\n"
" Uses type-aware resolution to apply defaults from Defaulted types.\n"
).
-spec extract_misc_metadata(list(caffeine_lang@common@helpers:value_tuple())) -> gleam@dict:dict(binary(), binary()).
extract_misc_metadata(Value_tuples) ->
_pipe = Value_tuples,
_pipe@1 = gleam@list:filter_map(
_pipe,
fun(Value_tuple) -> case erlang:element(2, Value_tuple) of
<<"window_in_days"/utf8>> ->
{error, nil};
<<"threshold"/utf8>> ->
{error, nil};
<<"value"/utf8>> ->
{error, nil};
_ ->
case resolve_value_for_tag(Value_tuple) of
{ok, Value_string} ->
{ok, {erlang:element(2, Value_tuple), Value_string}};
{error, _} ->
{error, nil}
end
end end
),
maps:from_list(_pipe@1).
-file("src/caffeine_lang/parser/ir_builder.gleam", 59).
?DOC(" Build intermediate representations from validated expectations for a single file.\n").
-spec build(
list({caffeine_lang@parser@expectations:expectation(),
caffeine_lang@parser@blueprints:blueprint()}),
binary()
) -> list(caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()).
build(Expectations_blueprint_collection, File_path) ->
{Org, Team, Service} = extract_path_prefix(File_path),
_pipe = Expectations_blueprint_collection,
gleam@list:map(
_pipe,
fun(Expectation_and_blueprint_pair) ->
{Expectation, Blueprint} = Expectation_and_blueprint_pair,
Merged_inputs = maps:merge(
erlang:element(5, Blueprint),
erlang:element(4, Expectation)
),
Value_tuples = build_value_tuples(
Merged_inputs,
erlang:element(4, Blueprint)
),
Misc_metadata = extract_misc_metadata(Value_tuples),
Unique_name = <<<<<<<<Org/binary, "_"/utf8>>/binary,
Service/binary>>/binary,
"_"/utf8>>/binary,
(erlang:element(2, Expectation))/binary>>,
{intermediate_representation,
{intermediate_representation_meta_data,
erlang:element(2, Expectation),
Org,
Service,
erlang:element(2, Blueprint),
Team,
Misc_metadata},
Unique_name,
erlang:element(3, Blueprint),
Value_tuples,
none}
end
).
-file("src/caffeine_lang/parser/ir_builder.gleam", 18).
?DOC(false).
-spec build_all(
list({list({caffeine_lang@parser@expectations:expectation(),
caffeine_lang@parser@blueprints:blueprint()}),
binary()})
) -> list(caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()).
build_all(Expectations_with_paths) ->
_pipe = Expectations_with_paths,
_pipe@1 = gleam@list:map(
_pipe,
fun(Pair) ->
{Expectations_blueprint_collection, File_path} = Pair,
build(Expectations_blueprint_collection, File_path)
end
),
lists:append(_pipe@1).