Current section

Files

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

src/caffeine_lang@parser@artifacts.erl

-module(caffeine_lang@parser@artifacts).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/parser/artifacts.gleam").
-export([parse_semver/1, parse_standard_library/0, parse_from_file/1]).
-export_type([artifact/0, semver/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 artifact() :: {artifact,
binary(),
semver(),
gleam@dict:dict(binary(), caffeine_lang@common@helpers:accepted_types()),
gleam@dict:dict(binary(), caffeine_lang@common@helpers:accepted_types())}.
-type semver() :: {semver, integer(), integer(), integer()}.
-file("src/caffeine_lang/parser/artifacts.gleam", 75).
?DOC(
" Parse a single semver part - must be non-negative and no leading zeros\n"
" (except for \"0\" itself).\n"
).
-spec parse_semver_part(binary()) -> {ok, integer()} | {error, nil}.
parse_semver_part(S) ->
case S of
<<""/utf8>> ->
{error, nil};
<<"0"/utf8>> ->
{ok, 0};
_ ->
case gleam_stdlib:string_starts_with(S, <<"0"/utf8>>) orelse gleam_stdlib:string_starts_with(
S,
<<"-"/utf8>>
) of
true ->
{error, nil};
false ->
gleam_stdlib:parse_int(S)
end
end.
-file("src/caffeine_lang/parser/artifacts.gleam", 64).
?DOC(false).
-spec parse_semver(binary()) -> {ok, semver()} | {error, nil}.
parse_semver(Version_string) ->
case begin
_pipe = Version_string,
_pipe@1 = gleam@string:split(_pipe, <<"."/utf8>>),
gleam@list:map(_pipe@1, fun parse_semver_part/1)
end of
[{ok, Major}, {ok, Minor}, {ok, Patch}] ->
{ok, {semver, Major, Minor, Patch}};
_ ->
{error, nil}
end.
-file("src/caffeine_lang/parser/artifacts.gleam", 88).
?DOC(" Decoder for semantic version strings (e.g., \"1.2.3\").\n").
-spec semantic_version_decoder() -> gleam@dynamic@decode:decoder(semver()).
semantic_version_decoder() ->
Err_default = {semver, 0, 0, 0},
gleam@dynamic@decode:new_primitive_decoder(
<<"Semver"/utf8>>,
fun(Dyn) ->
gleam@result:'try'(
begin
_pipe = gleam@dynamic@decode:run(
Dyn,
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@result:replace_error(_pipe, Err_default)
end,
fun(Str) -> _pipe@1 = parse_semver(Str),
gleam@result:replace_error(_pipe@1, Err_default) end
)
end
).
-file("src/caffeine_lang/parser/artifacts.gleam", 98).
-spec parse_from_string(binary()) -> {ok, list(artifact())} |
{error, gleam@json:decode_error()}.
parse_from_string(Json_string) ->
Artifact_decoder = begin
gleam@dynamic@decode:field(
<<"name"/utf8>>,
caffeine_lang@common@decoders:non_empty_string_decoder(),
fun(Name) ->
gleam@dynamic@decode:field(
<<"version"/utf8>>,
semantic_version_decoder(),
fun(Version) ->
gleam@dynamic@decode:field(
<<"inherited_params"/utf8>>,
gleam@dynamic@decode:dict(
{decoder,
fun gleam@dynamic@decode:decode_string/1},
caffeine_lang@common@decoders:accepted_types_decoder(
)
),
fun(Inherited_params) ->
gleam@dynamic@decode:field(
<<"required_params"/utf8>>,
gleam@dynamic@decode:dict(
{decoder,
fun gleam@dynamic@decode:decode_string/1},
caffeine_lang@common@decoders:accepted_types_decoder(
)
),
fun(Required_params) ->
gleam@dynamic@decode:success(
{artifact,
Name,
Version,
Inherited_params,
Required_params}
)
end
)
end
)
end
)
end
)
end,
Artifacts_decoded = begin
gleam@dynamic@decode:field(
<<"artifacts"/utf8>>,
gleam@dynamic@decode:list(Artifact_decoder),
fun(Artifacts) -> gleam@dynamic@decode:success(Artifacts) end
)
end,
gleam@json:parse(Json_string, Artifacts_decoded).
-file("src/caffeine_lang/parser/artifacts.gleam", 44).
?DOC(" The actual, common parsing logic.\n").
-spec internal_parse_from_string(binary()) -> {ok, list(artifact())} |
{error, caffeine_lang@common@errors:compilation_error()}.
internal_parse_from_string(Content) ->
gleam@result:'try'(case parse_from_string(Content) of
{ok, Artifacts} ->
{ok, Artifacts};
{error, Err} ->
{error,
caffeine_lang@common@errors:format_json_decode_error(Err)}
end, fun(Artifacts@1) ->
gleam@result:'try'(
caffeine_lang@common@validations:validate_relevant_uniqueness(
Artifacts@1,
fun(A) -> erlang:element(2, A) end,
<<"artifact names"/utf8>>
),
fun(_) -> {ok, Artifacts@1} end
)
end).
-file("src/caffeine_lang/parser/artifacts.gleam", 32).
?DOC(" Parses the embedded standard library artifacts.\n").
-spec parse_standard_library() -> {ok, list(artifact())} |
{error, caffeine_lang@common@errors:compilation_error()}.
parse_standard_library() ->
internal_parse_from_string(
<<"
{
\"artifacts\": [
{
\"name\": \"SLO\",
\"version\": \"0.0.1\",
\"inherited_params\": { \"threshold\": \"Float\", \"window_in_days\": \"Integer\" },
\"required_params\": { \"queries\": \"Dict(String, String)\", \"value\": \"String\", \"vendor\": \"String\"}
}
]
}
"/utf8>>
).
-file("src/caffeine_lang/parser/artifacts.gleam", 37).
?DOC(" Parses an artifact from an artifacts.json file.\n").
-spec parse_from_file(binary()) -> {ok, list(artifact())} |
{error, caffeine_lang@common@errors:compilation_error()}.
parse_from_file(File_path) ->
gleam@result:'try'(
caffeine_lang@common@helpers:json_from_file(File_path),
fun(Json_string) -> internal_parse_from_string(Json_string) end
).