Current section

Files

Jump to
caffeine_lang src caffeine_lang@linker@expectations.erl
Raw

src/caffeine_lang@linker@expectations.erl

-module(caffeine_lang@linker@expectations).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/linker/expectations.gleam").
-export([validate_expectations/4]).
-export_type([expectation/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 expectation() :: {expectation,
binary(),
gleam@option:option(binary()),
gleam@dict:dict(binary(), caffeine_lang@value:value()),
gleam@option:option(binary())}.
-file("src/caffeine_lang/linker/expectations.gleam", 131).
?DOC(
" Validates unmeasured expectations against restricted SLO params.\n"
" Unmeasured expectations may only provide: threshold, window_in_days, depends_on.\n"
).
-spec validate_unmeasured_expectations(
list(expectation()),
gleam@dict:dict(binary(), caffeine_lang@linker@slo_params:param_info()),
binary()
) -> {ok,
list({expectation(),
gleam@option:option(caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated()))})} |
{error, caffeine_lang@errors:compilation_error()}.
validate_unmeasured_expectations(Expectations, Params, Source_path) ->
{Org, Team, Service} = caffeine_lang@helpers:extract_path_prefix(
Source_path
),
Path_prefix = <<<<<<<<<<Org/binary, "."/utf8>>/binary, Team/binary>>/binary,
"."/utf8>>/binary,
Service/binary>>/binary,
"."/utf8>>,
Restricted_params = caffeine_lang@linker@slo_params:unmeasured_param_types(
Params
),
Input_param_collections = begin
_pipe = Expectations,
gleam@list:map(_pipe, fun(E) -> {E, Restricted_params} end)
end,
gleam@result:'try'(
caffeine_lang@linker@validations:validate_inputs_for_collection(
Input_param_collections,
fun(Expectation) -> erlang:element(4, Expectation) end,
fun(Params@1) -> Params@1 end,
fun(Expectation@1) ->
<<<<<<"expectation '"/utf8, Path_prefix/binary>>/binary,
(erlang:element(2, Expectation@1))/binary>>/binary,
"'"/utf8>>
end,
true
),
fun(_) ->
{ok,
begin
_pipe@1 = Expectations,
gleam@list:map(_pipe@1, fun(E@1) -> {E@1, none} end)
end}
end
).
-file("src/caffeine_lang/linker/expectations.gleam", 201).
-spec check_input_overshadowing(
list({expectation(),
caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated())}),
binary()
) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}.
check_input_overshadowing(Expectations_measurement_collection, Path_prefix) ->
caffeine_lang@linker@validations:validate_no_overshadowing(
Expectations_measurement_collection,
fun(Expectation) -> erlang:element(4, Expectation) end,
fun(Measurement) -> erlang:element(4, Measurement) end,
fun(Expectation@1) ->
<<<<<<"expectation '"/utf8, Path_prefix/binary>>/binary,
(erlang:element(2, Expectation@1))/binary>>/binary,
"' - overshadowing inputs from measurement: "/utf8>>
end
).
-file("src/caffeine_lang/linker/expectations.gleam", 165).
?DOC(
" Validates that every measured expectation's measurement_ref matches an existing measurement.\n"
" Only called with measured expectations (those with Some(ref)).\n"
" Includes Levenshtein-based \"did you mean?\" suggestions for unknown refs.\n"
).
-spec validate_measurement_refs(
list(expectation()),
list(caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated()))
) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}.
validate_measurement_refs(Expectations, Measurements) ->
Measurement_names = gleam@list:map(
Measurements,
fun(B) -> erlang:element(2, B) end
),
Measurement_name_set = gleam@set:from_list(Measurement_names),
Missing = begin
_pipe = Expectations,
gleam@list:filter_map(_pipe, fun(E) -> case erlang:element(3, E) of
{some, Ref} ->
case gleam@set:contains(Measurement_name_set, Ref) of
true ->
{error, nil};
false ->
{ok, Ref}
end;
none ->
{error, nil}
end end)
end,
case Missing of
[] ->
{ok, nil};
[Single_ref] ->
Suggestion = caffeine_lang@string_distance:closest_match(
Single_ref,
Measurement_names
),
{error,
{linker_parse_error,
<<"Unknown measurement reference: "/utf8,
Single_ref/binary>>,
begin
_record = caffeine_lang@errors:empty_context(),
{error_context,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
Suggestion}
end}};
_ ->
{error,
caffeine_lang@errors:linker_parse_error(
<<"Unknown measurement reference(s): "/utf8,
(gleam@string:join(Missing, <<", "/utf8>>))/binary>>
)}
end.
-file("src/caffeine_lang/linker/expectations.gleam", 76).
?DOC(" Validates measured expectations against their measurements.\n").
-spec validate_measured_expectations(
list(expectation()),
list(caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated())),
binary()
) -> {ok,
list({expectation(),
gleam@option:option(caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated()))})} |
{error, caffeine_lang@errors:compilation_error()}.
validate_measured_expectations(Expectations, Measurements, Source_path) ->
gleam@result:'try'(
validate_measurement_refs(Expectations, Measurements),
fun(_) ->
Expectations_measurement_collection = caffeine_lang@helpers:map_reference_to_referrer_over_collection(
Measurements,
Expectations,
fun(B) -> erlang:element(2, B) end,
fun(E) ->
Ref@1 = case erlang:element(3, E) of
{some, Ref} -> Ref;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"caffeine_lang/linker/expectations"/utf8>>,
function => <<"validate_measured_expectations"/utf8>>,
line => 94,
value => _assert_fail,
start => 3344,
'end' => 3391,
pattern_start => 3355,
pattern_end => 3371})
end,
Ref@1
end
),
{Org, Team, Service} = caffeine_lang@helpers:extract_path_prefix(
Source_path
),
Path_prefix = <<<<<<<<<<Org/binary, "."/utf8>>/binary, Team/binary>>/binary,
"."/utf8>>/binary,
Service/binary>>/binary,
"."/utf8>>,
gleam@result:'try'(
check_input_overshadowing(
Expectations_measurement_collection,
Path_prefix
),
fun(_) ->
gleam@result:'try'(
caffeine_lang@linker@validations:validate_inputs_for_collection(
Expectations_measurement_collection,
fun(Expectation) ->
erlang:element(4, Expectation)
end,
fun(Measurement) ->
_pipe = erlang:element(3, Measurement),
gleam@dict:filter(
_pipe,
fun(Key, _) ->
not gleam@dict:has_key(
erlang:element(4, Measurement),
Key
)
end
)
end,
fun(Expectation@1) ->
<<<<<<"expectation '"/utf8, Path_prefix/binary>>/binary,
(erlang:element(2, Expectation@1))/binary>>/binary,
"'"/utf8>>
end,
false
),
fun(_) ->
{ok,
begin
_pipe@1 = Expectations_measurement_collection,
gleam@list:map(
_pipe@1,
fun(Pair) ->
{erlang:element(1, Pair),
{some, erlang:element(2, Pair)}}
end
)
end}
end
)
end
)
end
).
-file("src/caffeine_lang/linker/expectations.gleam", 38).
?DOC(false).
-spec validate_expectations(
list(expectation()),
list(caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated())),
gleam@dict:dict(binary(), caffeine_lang@linker@slo_params:param_info()),
binary()
) -> {ok,
list({expectation(),
gleam@option:option(caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated()))})} |
{error, caffeine_lang@errors:compilation_error()}.
validate_expectations(Expectations, Measurements, Slo_params, Source_path) ->
{Measured, Unmeasured} = gleam@list:partition(
Expectations,
fun(E) -> gleam@option:is_some(erlang:element(3, E)) end
),
gleam@result:'try'(
caffeine_lang@linker@validations:validate_relevant_uniqueness(
Expectations,
fun(E@1) -> erlang:element(2, E@1) end,
<<"expectation names"/utf8>>
),
fun(_) ->
gleam@result:'try'(
validate_measured_expectations(
Measured,
Measurements,
Source_path
),
fun(Measured_pairs) ->
gleam@result:'try'(
validate_unmeasured_expectations(
Unmeasured,
Slo_params,
Source_path
),
fun(Unmeasured_pairs) ->
{ok, lists:append(Measured_pairs, Unmeasured_pairs)}
end
)
end
)
end
).