-module(drip@internal@registry). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/drip/internal/registry.gleam"). -export([fetch/1, resolve_elements/2]). -export_type([element/0, walk/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. ?MODULEDOC(false). -type element() :: {element, binary(), list(binary()), list(binary()), list(binary())}. -type walk() :: {walk, list(binary()), list(element())}. -file("src/drip/internal/registry.gleam", 77). ?DOC(false). -spec has_separator(binary()) -> boolean(). has_separator(Filename) -> gleam_stdlib:contains_string(Filename, <<"/"/utf8>>) orelse gleam_stdlib:contains_string( Filename, <<"\\"/utf8>> ). -file("src/drip/internal/registry.gleam", 70). ?DOC(false). -spec is_supported_filename(binary()) -> boolean(). is_supported_filename(Filename) -> (((Filename /= <<""/utf8>>) andalso (Filename /= <<"."/utf8>>)) andalso (Filename /= <<".."/utf8>>)) andalso not has_separator(Filename). -file("src/drip/internal/registry.gleam", 61). ?DOC(false). -spec validate_files(list(element())) -> {ok, nil} | {error, drip@internal@error:error()}. validate_files(Registry) -> gleam@list:try_each( Registry, fun(Element) -> gleam@list:try_each( erlang:element(5, Element), fun(File) -> case is_supported_filename(File) of true -> {ok, nil}; false -> {error, {unsupported_registry_file, erlang:element(2, Element), File}} end end ) end ). -file("src/drip/internal/registry.gleam", 103). ?DOC(false). -spec element_decoder() -> gleam@dynamic@decode:decoder(element()). element_decoder() -> gleam@dynamic@decode:field( <<"name"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Name) -> gleam@dynamic@decode:field( <<"registry_dependencies"/utf8>>, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ), fun(Registry_dependencies) -> gleam@dynamic@decode:field( <<"dependencies"/utf8>>, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ), fun(Dependencies) -> gleam@dynamic@decode:field( <<"files"/utf8>>, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ), fun(Files) -> gleam@dynamic@decode:success( {element, Name, Registry_dependencies, Dependencies, Files} ) end ) end ) end ) end ). -file("src/drip/internal/registry.gleam", 98). ?DOC(false). -spec registry_decoder() -> gleam@dynamic@decode:decoder(list(element())). registry_decoder() -> gleam@dynamic@decode:field( <<"elements"/utf8>>, gleam@dynamic@decode:list(element_decoder()), fun(Elements) -> gleam@dynamic@decode:success(Elements) end ). -file("src/drip/internal/registry.gleam", 94). ?DOC(false). -spec decode(binary()) -> {ok, list(element())} | {error, gleam@json:decode_error()}. decode(Json) -> gleam@json:parse(Json, registry_decoder()). -file("src/drip/internal/registry.gleam", 89). ?DOC(false). -spec schema_version_decoder() -> gleam@dynamic@decode:decoder(integer()). schema_version_decoder() -> gleam@dynamic@decode:field( <<"schema_version"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Version) -> gleam@dynamic@decode:success(Version) end ). -file("src/drip/internal/registry.gleam", 85). ?DOC(false). -spec decode_schema_version(binary()) -> {ok, integer()} | {error, gleam@json:decode_error()}. decode_schema_version(Json) -> gleam@json:parse(Json, schema_version_decoder()). -file("src/drip/internal/registry.gleam", 42). ?DOC(false). -spec validate_schema_version(binary()) -> {ok, nil} | {error, drip@internal@error:error()}. validate_schema_version(Body) -> case decode_schema_version(Body) of {ok, Version} -> case Version =< 1 of true -> {ok, nil}; false -> {error, {unsupported_registry_schema_version, Version, 1}} end; {error, Cause} -> {error, {failed_to_decode_registry_file, <<"registry.json"/utf8>>, Cause}} end. -file("src/drip/internal/registry.gleam", 27). ?DOC(false). -spec fetch(drip@internal@source:source()) -> {ok, list(element())} | {error, drip@internal@error:error()}. fetch(Source) -> gleam@result:'try'( drip@internal@source:fetch(Source, <<"registry.json"/utf8>>), fun(Body) -> gleam@result:'try'( validate_schema_version(Body), fun(_) -> gleam@result:'try'( begin _pipe = decode(Body), gleam@result:map_error( _pipe, fun(Cause) -> {failed_to_decode_registry_file, <<"registry.json"/utf8>>, Cause} end ) end, fun(Registry) -> gleam@result:'try'( validate_files(Registry), fun(_) -> {ok, Registry} end ) end ) end ) end ). -file("src/drip/internal/registry.gleam", 116). ?DOC(false). -spec find(list(element()), binary()) -> {ok, element()} | {error, nil}. find(Registry, Name) -> gleam@list:find( Registry, fun(Element) -> erlang:element(2, Element) =:= Name end ). -file("src/drip/internal/registry.gleam", 149). ?DOC(false). -spec visit(binary(), list(element()), list(binary()), list(element())) -> {ok, walk()} | {error, drip@internal@error:error()}. visit(Name, Registry, Seen, Acc) -> case gleam@list:contains(Seen, Name) of true -> {ok, {walk, Seen, Acc}}; false -> case find(Registry, Name) of {error, nil} -> {error, {unknown_element, Name}}; {ok, Element} -> gleam@result:map( visit_all( erlang:element(3, Element), Registry, [Name | Seen], Acc ), fun(_use0) -> {walk, Seen@1, Acc@1} = _use0, {walk, Seen@1, [Element | Acc@1]} end ) end end. -file("src/drip/internal/registry.gleam", 134). ?DOC(false). -spec visit_all( list(binary()), list(element()), list(binary()), list(element()) ) -> {ok, walk()} | {error, drip@internal@error:error()}. visit_all(Names, Registry, Seen, Acc) -> case Names of [] -> {ok, {walk, Seen, Acc}}; [Name | Rest] -> gleam@result:'try'( visit(Name, Registry, Seen, Acc), fun(_use0) -> {walk, Seen@1, Acc@1} = _use0, visit_all(Rest, Registry, Seen@1, Acc@1) end ) end. -file("src/drip/internal/registry.gleam", 122). ?DOC(false). -spec resolve_elements(list(element()), list(binary())) -> {ok, list(element())} | {error, drip@internal@error:error()}. resolve_elements(Registry, Names) -> gleam@result:map( visit_all(Names, Registry, [], []), fun(_use0) -> {walk, _, Acc} = _use0, lists:reverse(Acc) end ).