-module(caffeine_lang@linker@validations). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_lang/linker/validations.gleam"). -export([validate_value_type/3, inputs_validator/3, known_external_indicator_sources/0, validate_external_indicator_sources/2, validate_relevant_uniqueness/3, validate_inputs_for_collection/5, check_collection_key_overshadowing/3, validate_no_overshadowing/4]). -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/linker/validations.gleam", 14). ?DOC(false). -spec validate_value_type( caffeine_lang@value:value(), caffeine_lang@types:accepted_types(), binary() ) -> {ok, caffeine_lang@value:value()} | {error, caffeine_lang@errors:compilation_error()}. validate_value_type(Val, Expected_type, Type_key_identifier) -> _pipe = caffeine_lang@types:validate_value(Expected_type, Val), gleam@result:map_error( _pipe, fun(Err) -> caffeine_lang@errors:linker_value_validation_error( caffeine_lang@errors:format_validation_error_message( Err, {some, Type_key_identifier}, {some, Val} ) ) end ). -file("src/caffeine_lang/linker/validations.gleam", 35). ?DOC(false). -spec inputs_validator( gleam@dict:dict(binary(), caffeine_lang@types:accepted_types()), gleam@dict:dict(binary(), caffeine_lang@value:value()), boolean() ) -> {ok, nil} | {error, binary()}. inputs_validator(Params, Inputs, Missing_inputs_ok) -> Required_params = begin _pipe = Params, gleam@dict:filter( _pipe, fun(_, Typ) -> not caffeine_lang@types:is_optional_or_defaulted(Typ) end ) end, Required_param_keys = begin _pipe@1 = Required_params, _pipe@2 = maps:keys(_pipe@1), gleam@set:from_list(_pipe@2) end, Param_keys = begin _pipe@3 = Params, _pipe@4 = maps:keys(_pipe@3), gleam@set:from_list(_pipe@4) end, Input_keys = begin _pipe@5 = Inputs, _pipe@6 = maps:keys(_pipe@5), gleam@set:from_list(_pipe@6) end, Missing_required_keys = begin _pipe@7 = gleam@set:difference(Required_param_keys, Input_keys), gleam@set:to_list(_pipe@7) end, Keys_only_in_inputs = begin _pipe@8 = gleam@set:difference(Input_keys, Param_keys), gleam@set:to_list(_pipe@8) end, gleam@result:'try'( case {Missing_required_keys, Keys_only_in_inputs, Missing_inputs_ok} of {[], [], _} -> {ok, nil}; {_, [], true} -> {ok, nil}; {_, [], false} -> {error, <<"Missing keys in input: "/utf8, (begin _pipe@9 = Missing_required_keys, gleam@string:join(_pipe@9, <<", "/utf8>>) end)/binary>>}; {[], _, _} -> {error, <<"Extra keys in input: "/utf8, (begin _pipe@10 = Keys_only_in_inputs, gleam@string:join(_pipe@10, <<", "/utf8>>) end)/binary>>}; {_, _, true} -> {error, <<"Extra keys in input: "/utf8, (begin _pipe@11 = Keys_only_in_inputs, gleam@string:join(_pipe@11, <<", "/utf8>>) end)/binary>>}; {_, _, false} -> {error, <<<<<<"Extra keys in input: "/utf8, (begin _pipe@12 = Keys_only_in_inputs, gleam@string:join(_pipe@12, <<", "/utf8>>) end)/binary>>/binary, " and missing keys in input: "/utf8>>/binary, (begin _pipe@13 = Missing_required_keys, gleam@string:join(_pipe@13, <<", "/utf8>>) end)/binary>>} end, fun(_) -> Type_validation_errors = begin _pipe@14 = Inputs, _pipe@15 = maps:to_list(_pipe@14), _pipe@17 = gleam@list:filter_map( _pipe@15, fun(Pair) -> {Key, Value} = Pair, case begin _pipe@16 = Params, gleam_stdlib:map_get(_pipe@16, Key) end of {error, nil} -> {error, nil}; {ok, Expected_type} -> case validate_value_type( Value, Expected_type, Key ) of {ok, _} -> {error, nil}; {error, Errs} -> {ok, Errs} end end end ), _pipe@18 = gleam@list:map( _pipe@17, fun caffeine_lang@errors:to_message/1 ), gleam@string:join(_pipe@18, <<", "/utf8>>) end, case Type_validation_errors of <<""/utf8>> -> {ok, nil}; _ -> {error, Type_validation_errors} end end ). -file("src/caffeine_lang/linker/validations.gleam", 115). ?DOC(false). -spec known_external_indicator_sources() -> gleam@set:set(binary()). known_external_indicator_sources() -> gleam@set:from_list([<<"langfuse"/utf8>>]). -file("src/caffeine_lang/linker/validations.gleam", 124). ?DOC(false). -spec validate_external_indicator_sources( binary(), gleam@dict:dict(binary(), caffeine_lang@value:value()) ) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}. validate_external_indicator_sources(Measurement_name, Inputs) -> case gleam_stdlib:map_get(Inputs, <<"indicators"/utf8>>) of {error, _} -> {ok, nil}; {ok, {dict_value, D}} -> Unknown = begin _pipe = D, _pipe@1 = maps:to_list(_pipe), _pipe@2 = gleam@list:filter_map( _pipe@1, fun(Pair) -> {_, Val} = Pair, case Val of {external_indicator_value, Source, _, _} -> case gleam@set:contains( known_external_indicator_sources(), Source ) of true -> {error, nil}; false -> {ok, Source} end; _ -> {error, nil} end end ), _pipe@3 = gleam@list:unique(_pipe@2), gleam@list:sort(_pipe@3, fun gleam@string:compare/2) end, case Unknown of [] -> {ok, nil}; Sources -> {error, caffeine_lang@errors:linker_value_validation_error( <<<<<<"measurement '"/utf8, Measurement_name/binary>>/binary, "' - unknown external indicator source(s): "/utf8>>/binary, (gleam@string:join(Sources, <<", "/utf8>>))/binary>> )} end; {ok, _} -> {ok, nil} end. -file("src/caffeine_lang/linker/validations.gleam", 167). ?DOC(false). -spec validate_relevant_uniqueness(list(KBS), fun((KBS) -> binary()), binary()) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}. validate_relevant_uniqueness(Items, Fetch_property, Thing_label) -> Dupe_names = begin _pipe = Items, _pipe@1 = gleam@list:group( _pipe, fun(Thing) -> Fetch_property(Thing) end ), _pipe@2 = gleam@dict:filter( _pipe@1, fun(_, Occurrences) -> case Occurrences of [_, _ | _] -> true; _ -> false end end ), maps:keys(_pipe@2) end, case Dupe_names of [] -> {ok, nil}; _ -> {error, caffeine_lang@errors:linker_duplicate_error( <<<<<<"Duplicate "/utf8, Thing_label/binary>>/binary, ": "/utf8>>/binary, (begin _pipe@3 = Dupe_names, gleam@string:join(_pipe@3, <<", "/utf8>>) end)/binary>> )} end. -file("src/caffeine_lang/linker/validations.gleam", 198). ?DOC(false). -spec validate_inputs_for_collection( list({KBW, KBX}), fun((KBW) -> gleam@dict:dict(binary(), caffeine_lang@value:value())), fun((KBX) -> gleam@dict:dict(binary(), caffeine_lang@types:accepted_types())), fun((KBW) -> binary()), boolean() ) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}. validate_inputs_for_collection( Input_param_collections, Get_inputs, Get_params, Get_identifier, Missing_inputs_ok ) -> Validation_errors = begin _pipe = Input_param_collections, _pipe@1 = gleam@list:filter_map( _pipe, fun(Collection) -> {Input_collection, Param_collection} = Collection, case inputs_validator( Get_params(Param_collection), Get_inputs(Input_collection), Missing_inputs_ok ) of {ok, _} -> {error, nil}; {error, Msg} -> {ok, <<<<(Get_identifier(Input_collection))/binary, " - "/utf8>>/binary, Msg/binary>>} end end ), gleam@string:join(_pipe@1, <<", "/utf8>>) end, case Validation_errors of <<""/utf8>> -> {ok, nil}; _ -> {error, caffeine_lang@errors:linker_value_validation_error( <<"Input validation errors: "/utf8, Validation_errors/binary>> )} end. -file("src/caffeine_lang/linker/validations.gleam", 266). ?DOC(false). -spec check_collection_key_overshadowing( gleam@dict:dict(binary(), any()), gleam@dict:dict(binary(), any()), binary() ) -> {ok, nil} | {error, binary()}. check_collection_key_overshadowing( Reference_collection, Referrer_collection, Error_msg ) -> Reference_names = begin _pipe = Reference_collection, _pipe@1 = maps:keys(_pipe), gleam@set:from_list(_pipe@1) end, Referrer_names = begin _pipe@2 = Referrer_collection, _pipe@3 = maps:keys(_pipe@2), gleam@set:from_list(_pipe@3) end, Overshadowing_params = begin _pipe@4 = gleam@set:intersection(Reference_names, Referrer_names), gleam@set:to_list(_pipe@4) end, case Overshadowing_params of [] -> {ok, nil}; _ -> {error, <>) end)/binary>>} end. -file("src/caffeine_lang/linker/validations.gleam", 234). ?DOC(false). -spec validate_no_overshadowing( list({KCF, KCG}), fun((KCF) -> gleam@dict:dict(binary(), any())), fun((KCG) -> gleam@dict:dict(binary(), any())), fun((KCF) -> binary()) ) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}. validate_no_overshadowing( Items, Get_check_collection, Get_against_collection, Get_error_label ) -> Overshadow_errors = begin _pipe = Items, _pipe@1 = gleam@list:filter_map( _pipe, fun(Pair) -> {Item, Against} = Pair, case check_collection_key_overshadowing( Get_check_collection(Item), Get_against_collection(Against), Get_error_label(Item) ) of {ok, _} -> {error, nil}; {error, Msg} -> {ok, Msg} end end ), gleam@string:join(_pipe@1, <<", "/utf8>>) end, case Overshadow_errors of <<""/utf8>> -> {ok, nil}; _ -> {error, caffeine_lang@errors:linker_duplicate_error(Overshadow_errors)} end.