-module(drip@internal@source). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/drip/internal/source.gleam"). -export([parse/1, fetch/2]). -export_type([source/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). -opaque source() :: {http, binary()} | {local, binary()}. -file("src/drip/internal/source.gleam", 31). ?DOC(false). -spec is_http(binary()) -> boolean(). is_http(Raw) -> Lower = string:lowercase(Raw), gleam_stdlib:string_starts_with(Lower, <<"http://"/utf8>>) orelse gleam_stdlib:string_starts_with( Lower, <<"https://"/utf8>> ). -file("src/drip/internal/source.gleam", 36). ?DOC(false). -spec trim_trailing_slash(binary()) -> binary(). trim_trailing_slash(Raw) -> case gleam_stdlib:string_ends_with(Raw, <<"/"/utf8>>) of true -> trim_trailing_slash(gleam@string:drop_end(Raw, 1)); false -> Raw end. -file("src/drip/internal/source.gleam", 16). ?DOC(false). -spec parse(binary()) -> {ok, source()} | {error, drip@internal@error:error()}. parse(Raw) -> case begin _pipe = gleam@string:trim(Raw), trim_trailing_slash(_pipe) end of <<""/utf8>> -> {error, empty_source}; Source -> case is_http(Source) of true -> case gleam@http@request:to(Source) of {ok, _} -> {ok, {http, Source}}; {error, nil} -> {error, {invalid_source_url, Source}} end; false -> {ok, {local, Source}} end end. -file("src/drip/internal/source.gleam", 52). ?DOC(false). -spec read_file(binary()) -> {ok, binary()} | {error, drip@internal@error:error()}. read_file(Path) -> case simplifile:read(Path) of {ok, Content} -> {ok, Content}; {error, Cause} -> {error, {failed_to_read_source_file, Path, Cause}} end. -file("src/drip/internal/source.gleam", 59). ?DOC(false). -spec http_get(binary()) -> {ok, binary()} | {error, drip@internal@error:error()}. http_get(Url) -> gleam@result:'try'(case gleam@http@request:to(Url) of {ok, Request} -> {ok, gleam@http@request:set_header( Request, <<"user-agent"/utf8>>, <<"drip-cli"/utf8>> )}; {error, nil} -> {error, {invalid_source_url, Url}} end, fun(Request@1) -> Config = begin _pipe = gleam@httpc:configure(), _pipe@1 = gleam@httpc:follow_redirects(_pipe, true), gleam@httpc:timeout(_pipe@1, 30000) end, case gleam@httpc:dispatch(Config, Request@1) of {ok, Response} -> case erlang:element(2, Response) of Status when (Status >= 200) andalso (Status < 300) -> {ok, erlang:element(4, Response)}; 404 -> {error, {source_not_found, Url}}; Status@1 -> {error, {source_returned_bad_status, Url, Status@1}} end; {error, Cause} -> {error, {failed_to_fetch_source_file, Url, Cause}} end end). -file("src/drip/internal/source.gleam", 45). ?DOC(false). -spec fetch(source(), binary()) -> {ok, binary()} | {error, drip@internal@error:error()}. fetch(Source, Filename) -> case Source of {http, Base} -> http_get(<<<>/binary, Filename/binary>>); {local, Root} -> read_file(filepath:join(Root, Filename)) end.