aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/build/dev/erlang/gleam_http
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2023/build/dev/erlang/gleam_http')
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@@compile.erl157
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.cachebin0 -> 15491 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.cache_metabin0 -> 149 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.erl626
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.cachebin0 -> 4352 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.cache_metabin0 -> 161 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.erl153
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.cachebin0 -> 8252 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.cache_metabin0 -> 195 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.erl202
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.cachebin0 -> 5278 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.cache_metabin0 -> 150 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.erl97
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.cachebin0 -> 3223 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.cache_metabin0 -> 138 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.erl82
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam_http_native.erl88
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam_http_native.mjs38
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http.beambin0 -> 21920 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@cookie.beambin0 -> 7076 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@request.beambin0 -> 8976 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@response.beambin0 -> 5004 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@service.beambin0 -> 4308 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/ebin/gleam_http.app7
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/ebin/gleam_http_native.beambin0 -> 4952 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/include/gleam@http@cookie_Attributes.hrl8
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/include/gleam@http@request_Request.hrl10
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/include/gleam@http@response_Response.hrl5
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MoreRequiredForBody.hrl5
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MoreRequiredForHeaders.hrl4
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MultipartBody.hrl5
-rw-r--r--aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MultipartHeaders.hrl4
32 files changed, 1491 insertions, 0 deletions
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@@compile.erl b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@@compile.erl
new file mode 100644
index 0000000..543db88
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@@compile.erl
@@ -0,0 +1,157 @@
+#!/usr/bin/env escript
+
+% TODO: Don't concurrently print warnings and errors
+% TODO: Some tests
+
+-record(arguments, {lib = "./", out = "./", modules = []}).
+
+main(Args) ->
+ #arguments{out = Out, lib = Lib, modules = Modules} = parse(Args),
+ IsElixirModule = fun(Module) ->
+ filename:extension(Module) =:= ".ex"
+ end,
+ {ElixirModules, ErlangModules} = lists:partition(IsElixirModule, Modules),
+ ok = configure_logging(),
+ ok = add_lib_to_erlang_path(Lib),
+ ok = filelib:ensure_dir([Out, $/]),
+ {ErlangOk, _ErlangBeams} = compile_erlang(ErlangModules, Out),
+ {ElixirOk, _ElixirBeams} = case ErlangOk of
+ true -> compile_elixir(ElixirModules, Out);
+ false -> {false, []}
+ end,
+ case ErlangOk and ElixirOk of
+ true -> ok;
+ false -> erlang:halt(1)
+ end.
+
+compile_erlang(Modules, Out) ->
+ Workers = start_compiler_workers(Out),
+ ok = producer_loop(Modules, Workers),
+ collect_results({true, []}).
+
+collect_results(Acc = {Result, Beams}) ->
+ receive
+ {compiled, Beam} -> collect_results({Result, [Beam | Beams]});
+ failed -> collect_results({false, Beams})
+ after 0 -> Acc
+ end.
+
+producer_loop([], 0) ->
+ ok;
+producer_loop([], Workers) ->
+ receive
+ {work_please, _} -> producer_loop([], Workers - 1)
+ end;
+producer_loop([Module | Modules], Workers) ->
+ receive
+ {work_please, Worker} ->
+ erlang:send(Worker, {module, Module}),
+ producer_loop(Modules, Workers)
+ end.
+
+start_compiler_workers(Out) ->
+ Parent = self(),
+ NumSchedulers = erlang:system_info(schedulers),
+ SpawnWorker = fun(_) ->
+ erlang:spawn_link(fun() -> worker_loop(Parent, Out) end)
+ end,
+ lists:foreach(SpawnWorker, lists:seq(1, NumSchedulers)),
+ NumSchedulers.
+
+worker_loop(Parent, Out) ->
+ Options = [report_errors, report_warnings, debug_info, {outdir, Out}],
+ erlang:send(Parent, {work_please, self()}),
+ receive
+ {module, Module} ->
+ log({compiling, Module}),
+ case compile:file(Module, Options) of
+ {ok, ModuleName} ->
+ Beam = filename:join(Out, ModuleName) ++ ".beam",
+ Message = {compiled, Beam},
+ log(Message),
+ erlang:send(Parent, Message);
+ error ->
+ log({failed, Module}),
+ erlang:send(Parent, failed)
+ end,
+ worker_loop(Parent, Out)
+ end.
+
+compile_elixir(Modules, Out) ->
+ Error = [
+ "The program elixir was not found. Is it installed?",
+ $\n,
+ "Documentation for installing Elixir can be viewed here:",
+ $\n,
+ "https://elixir-lang.org/install.html"
+ ],
+ case Modules of
+ [] -> {true, []};
+ _ ->
+ log({starting, "compiler.app"}),
+ ok = application:start(compiler),
+ log({starting, "elixir.app"}),
+ case application:start(elixir) of
+ ok -> do_compile_elixir(Modules, Out);
+ _ ->
+ io:put_chars(standard_error, [Error, $\n]),
+ {false, []}
+ end
+ end.
+
+do_compile_elixir(Modules, Out) ->
+ ModuleBins = lists:map(fun(Module) ->
+ log({compiling, Module}),
+ list_to_binary(Module)
+ end, Modules),
+ OutBin = list_to_binary(Out),
+ Options = [{dest, OutBin}],
+ % Silence "redefining module" warnings.
+ % Compiled modules in the build directory are added to the code path.
+ % These warnings result from recompiling loaded modules.
+ % TODO: This line can likely be removed if/when the build directory is cleaned before every compilation.
+ 'Elixir.Code':compiler_options([{ignore_module_conflict, true}]),
+ case 'Elixir.Kernel.ParallelCompiler':compile_to_path(ModuleBins, OutBin, Options) of
+ {ok, ModuleAtoms, _} ->
+ ToBeam = fun(ModuleAtom) ->
+ Beam = filename:join(Out, atom_to_list(ModuleAtom)) ++ ".beam",
+ log({compiled, Beam}),
+ Beam
+ end,
+ {true, lists:map(ToBeam, ModuleAtoms)};
+ {error, Errors, _} ->
+ % Log all filenames associated with modules that failed to compile.
+ % Note: The compiler prints compilation errors upon encountering them.
+ ErrorFiles = lists:usort([File || {File, _, _} <- Errors]),
+ Log = fun(File) ->
+ log({failed, binary_to_list(File)})
+ end,
+ lists:foreach(Log, ErrorFiles),
+ {false, []};
+ _ -> {false, []}
+ end.
+
+add_lib_to_erlang_path(Lib) ->
+ code:add_paths(filelib:wildcard([Lib, "/*/ebin"])).
+
+parse(Args) ->
+ parse(Args, #arguments{}).
+
+parse([], Arguments) ->
+ Arguments;
+parse(["--lib", Lib | Rest], Arguments) ->
+ parse(Rest, Arguments#arguments{lib = Lib});
+parse(["--out", Out | Rest], Arguments) ->
+ parse(Rest, Arguments#arguments{out = Out});
+parse([Module | Rest], Arguments = #arguments{modules = Modules}) ->
+ parse(Rest, Arguments#arguments{modules = [Module | Modules]}).
+
+configure_logging() ->
+ Enabled = os:getenv("GLEAM_LOG") /= false,
+ persistent_term:put(gleam_logging_enabled, Enabled).
+
+log(Term) ->
+ case persistent_term:get(gleam_logging_enabled) of
+ true -> erlang:display(Term), ok;
+ false -> ok
+ end.
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.cache b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.cache
new file mode 100644
index 0000000..0b8931e
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.cache_meta b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.cache_meta
new file mode 100644
index 0000000..dc85da7
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.erl b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.erl
new file mode 100644
index 0000000..91ee6e8
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http.erl
@@ -0,0 +1,626 @@
+-module(gleam@http).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
+
+-export([parse_method/1, method_to_string/1, scheme_to_string/1, scheme_from_string/1, parse_content_disposition/1, parse_multipart_body/2, method_from_dynamic/1, parse_multipart_headers/2]).
+-export_type([method/0, scheme/0, multipart_headers/0, multipart_body/0, content_disposition/0]).
+
+-type method() :: get |
+ post |
+ head |
+ put |
+ delete |
+ trace |
+ connect |
+ options |
+ patch |
+ {other, binary()}.
+
+-type scheme() :: http | https.
+
+-type multipart_headers() :: {multipart_headers,
+ list({binary(), binary()}),
+ bitstring()} |
+ {more_required_for_headers,
+ fun((bitstring()) -> {ok, multipart_headers()} | {error, nil})}.
+
+-type multipart_body() :: {multipart_body, bitstring(), boolean(), bitstring()} |
+ {more_required_for_body,
+ bitstring(),
+ fun((bitstring()) -> {ok, multipart_body()} | {error, nil})}.
+
+-type content_disposition() :: {content_disposition,
+ binary(),
+ list({binary(), binary()})}.
+
+-spec parse_method(binary()) -> {ok, method()} | {error, nil}.
+parse_method(S) ->
+ case gleam@string:lowercase(S) of
+ <<"connect"/utf8>> ->
+ {ok, connect};
+
+ <<"delete"/utf8>> ->
+ {ok, delete};
+
+ <<"get"/utf8>> ->
+ {ok, get};
+
+ <<"head"/utf8>> ->
+ {ok, head};
+
+ <<"options"/utf8>> ->
+ {ok, options};
+
+ <<"patch"/utf8>> ->
+ {ok, patch};
+
+ <<"post"/utf8>> ->
+ {ok, post};
+
+ <<"put"/utf8>> ->
+ {ok, put};
+
+ <<"trace"/utf8>> ->
+ {ok, trace};
+
+ _ ->
+ {error, nil}
+ end.
+
+-spec method_to_string(method()) -> binary().
+method_to_string(Method) ->
+ case Method of
+ connect ->
+ <<"connect"/utf8>>;
+
+ delete ->
+ <<"delete"/utf8>>;
+
+ get ->
+ <<"get"/utf8>>;
+
+ head ->
+ <<"head"/utf8>>;
+
+ options ->
+ <<"options"/utf8>>;
+
+ patch ->
+ <<"patch"/utf8>>;
+
+ post ->
+ <<"post"/utf8>>;
+
+ put ->
+ <<"put"/utf8>>;
+
+ trace ->
+ <<"trace"/utf8>>;
+
+ {other, S} ->
+ S
+ end.
+
+-spec scheme_to_string(scheme()) -> binary().
+scheme_to_string(Scheme) ->
+ case Scheme of
+ http ->
+ <<"http"/utf8>>;
+
+ https ->
+ <<"https"/utf8>>
+ end.
+
+-spec scheme_from_string(binary()) -> {ok, scheme()} | {error, nil}.
+scheme_from_string(Scheme) ->
+ case gleam@string:lowercase(Scheme) of
+ <<"http"/utf8>> ->
+ {ok, http};
+
+ <<"https"/utf8>> ->
+ {ok, https};
+
+ _ ->
+ {error, nil}
+ end.
+
+-spec skip_whitespace(bitstring()) -> bitstring().
+skip_whitespace(Data) ->
+ case Data of
+ <<32, Data@1/binary>> ->
+ skip_whitespace(Data@1);
+
+ <<9, Data@1/binary>> ->
+ skip_whitespace(Data@1);
+
+ _ ->
+ Data
+ end.
+
+-spec more_please_headers(
+ fun((bitstring()) -> {ok, multipart_headers()} | {error, nil}),
+ bitstring()
+) -> {ok, multipart_headers()} | {error, nil}.
+more_please_headers(Continuation, Existing) ->
+ {ok,
+ {more_required_for_headers,
+ fun(More) ->
+ gleam@bool:guard(
+ More =:= <<>>,
+ {error, nil},
+ fun() ->
+ Continuation(<<Existing/bitstring, More/bitstring>>)
+ end
+ )
+ end}}.
+
+-spec parse_rfc_2045_parameter_quoted_value(binary(), binary(), binary()) -> {ok,
+ {{binary(), binary()}, binary()}} |
+ {error, nil}.
+parse_rfc_2045_parameter_quoted_value(Header, Name, Value) ->
+ case gleam@string:pop_grapheme(Header) of
+ {error, nil} ->
+ {error, nil};
+
+ {ok, {<<"\""/utf8>>, Rest}} ->
+ {ok, {{Name, Value}, Rest}};
+
+ {ok, {<<"\\"/utf8>>, Rest@1}} ->
+ gleam@result:'try'(
+ gleam@string:pop_grapheme(Rest@1),
+ fun(_use0) ->
+ {Grapheme, Rest@2} = _use0,
+ parse_rfc_2045_parameter_quoted_value(
+ Rest@2,
+ Name,
+ <<Value/binary, Grapheme/binary>>
+ )
+ end
+ );
+
+ {ok, {Grapheme@1, Rest@3}} ->
+ parse_rfc_2045_parameter_quoted_value(
+ Rest@3,
+ Name,
+ <<Value/binary, Grapheme@1/binary>>
+ )
+ end.
+
+-spec parse_rfc_2045_parameter_unquoted_value(binary(), binary(), binary()) -> {{binary(),
+ binary()},
+ binary()}.
+parse_rfc_2045_parameter_unquoted_value(Header, Name, Value) ->
+ case gleam@string:pop_grapheme(Header) of
+ {error, nil} ->
+ {{Name, Value}, Header};
+
+ {ok, {<<";"/utf8>>, Rest}} ->
+ {{Name, Value}, Rest};
+
+ {ok, {<<" "/utf8>>, Rest}} ->
+ {{Name, Value}, Rest};
+
+ {ok, {<<"\t"/utf8>>, Rest}} ->
+ {{Name, Value}, Rest};
+
+ {ok, {Grapheme, Rest@1}} ->
+ parse_rfc_2045_parameter_unquoted_value(
+ Rest@1,
+ Name,
+ <<Value/binary, Grapheme/binary>>
+ )
+ end.
+
+-spec parse_rfc_2045_parameter_value(binary(), binary()) -> {ok,
+ {{binary(), binary()}, binary()}} |
+ {error, nil}.
+parse_rfc_2045_parameter_value(Header, Name) ->
+ case gleam@string:pop_grapheme(Header) of
+ {error, nil} ->
+ {error, nil};
+
+ {ok, {<<"\""/utf8>>, Rest}} ->
+ parse_rfc_2045_parameter_quoted_value(Rest, Name, <<""/utf8>>);
+
+ {ok, {Grapheme, Rest@1}} ->
+ {ok,
+ parse_rfc_2045_parameter_unquoted_value(Rest@1, Name, Grapheme)}
+ end.
+
+-spec parse_rfc_2045_parameter(binary(), binary()) -> {ok,
+ {{binary(), binary()}, binary()}} |
+ {error, nil}.
+parse_rfc_2045_parameter(Header, Name) ->
+ gleam@result:'try'(
+ gleam@string:pop_grapheme(Header),
+ fun(_use0) ->
+ {Grapheme, Rest} = _use0,
+ case Grapheme of
+ <<"="/utf8>> ->
+ parse_rfc_2045_parameter_value(Rest, Name);
+
+ _ ->
+ parse_rfc_2045_parameter(
+ Rest,
+ <<Name/binary,
+ (gleam@string:lowercase(Grapheme))/binary>>
+ )
+ end
+ end
+ ).
+
+-spec parse_rfc_2045_parameters(binary(), list({binary(), binary()})) -> {ok,
+ list({binary(), binary()})} |
+ {error, nil}.
+parse_rfc_2045_parameters(Header, Parameters) ->
+ case gleam@string:pop_grapheme(Header) of
+ {error, nil} ->
+ {ok, gleam@list:reverse(Parameters)};
+
+ {ok, {<<";"/utf8>>, Rest}} ->
+ parse_rfc_2045_parameters(Rest, Parameters);
+
+ {ok, {<<" "/utf8>>, Rest}} ->
+ parse_rfc_2045_parameters(Rest, Parameters);
+
+ {ok, {<<"\t"/utf8>>, Rest}} ->
+ parse_rfc_2045_parameters(Rest, Parameters);
+
+ {ok, {Grapheme, Rest@1}} ->
+ Acc = gleam@string:lowercase(Grapheme),
+ gleam@result:'try'(
+ parse_rfc_2045_parameter(Rest@1, Acc),
+ fun(_use0) ->
+ {Parameter, Rest@2} = _use0,
+ parse_rfc_2045_parameters(Rest@2, [Parameter | Parameters])
+ end
+ )
+ end.
+
+-spec parse_content_disposition_type(binary(), binary()) -> {ok,
+ content_disposition()} |
+ {error, nil}.
+parse_content_disposition_type(Header, Name) ->
+ case gleam@string:pop_grapheme(Header) of
+ {error, nil} ->
+ {ok, {content_disposition, Name, []}};
+
+ {ok, {<<" "/utf8>>, Rest}} ->
+ Result = parse_rfc_2045_parameters(Rest, []),
+ gleam@result:map(
+ Result,
+ fun(Parameters) -> {content_disposition, Name, Parameters} end
+ );
+
+ {ok, {<<"\t"/utf8>>, Rest}} ->
+ Result = parse_rfc_2045_parameters(Rest, []),
+ gleam@result:map(
+ Result,
+ fun(Parameters) -> {content_disposition, Name, Parameters} end
+ );
+
+ {ok, {<<";"/utf8>>, Rest}} ->
+ Result = parse_rfc_2045_parameters(Rest, []),
+ gleam@result:map(
+ Result,
+ fun(Parameters) -> {content_disposition, Name, Parameters} end
+ );
+
+ {ok, {Grapheme, Rest@1}} ->
+ parse_content_disposition_type(
+ Rest@1,
+ <<Name/binary, (gleam@string:lowercase(Grapheme))/binary>>
+ )
+ end.
+
+-spec parse_content_disposition(binary()) -> {ok, content_disposition()} |
+ {error, nil}.
+parse_content_disposition(Header) ->
+ parse_content_disposition_type(Header, <<""/utf8>>).
+
+-spec more_please_body(
+ fun((bitstring()) -> {ok, multipart_body()} | {error, nil}),
+ bitstring(),
+ bitstring()
+) -> {ok, multipart_body()} | {error, nil}.
+more_please_body(Continuation, Chunk, Existing) ->
+ _pipe = fun(More) ->
+ gleam@bool:guard(
+ More =:= <<>>,
+ {error, nil},
+ fun() -> Continuation(<<Existing/bitstring, More/bitstring>>) end
+ )
+ end,
+ _pipe@1 = {more_required_for_body, Chunk, _pipe},
+ {ok, _pipe@1}.
+
+-spec parse_body_loop(bitstring(), bitstring(), bitstring()) -> {ok,
+ multipart_body()} |
+ {error, nil}.
+parse_body_loop(Data, Boundary, Body) ->
+ Dsize = erlang:byte_size(Data),
+ Bsize = erlang:byte_size(Boundary),
+ Required = 6 + Bsize,
+ case Data of
+ _ when Dsize < Required ->
+ more_please_body(
+ fun(_capture) -> parse_body_loop(_capture, Boundary, <<>>) end,
+ Body,
+ Data
+ );
+
+ <<13, 10, Data@1/binary>> ->
+ Desired = <<45, 45, Boundary/bitstring>>,
+ Size = erlang:byte_size(Desired),
+ Dsize@1 = erlang:byte_size(Data@1),
+ Prefix = gleam_stdlib:bit_array_slice(Data@1, 0, Size),
+ Rest = gleam_stdlib:bit_array_slice(Data@1, Size, Dsize@1 - Size),
+ case {Prefix =:= {ok, Desired}, Rest} of
+ {true, {ok, <<13, 10, _/binary>>}} ->
+ {ok, {multipart_body, Body, false, Data@1}};
+
+ {true, {ok, <<45, 45, Data@2/binary>>}} ->
+ {ok, {multipart_body, Body, true, Data@2}};
+
+ {false, _} ->
+ parse_body_loop(
+ Data@1,
+ Boundary,
+ <<Body/bitstring, 13, 10>>
+ );
+
+ {_, _} ->
+ {error, nil}
+ end;
+
+ <<Char, Data@3/binary>> ->
+ parse_body_loop(Data@3, Boundary, <<Body/bitstring, Char>>)
+ end.
+
+-spec parse_body_with_bit_array(bitstring(), bitstring()) -> {ok,
+ multipart_body()} |
+ {error, nil}.
+parse_body_with_bit_array(Data, Boundary) ->
+ Bsize = erlang:byte_size(Boundary),
+ Prefix = gleam_stdlib:bit_array_slice(Data, 0, 2 + Bsize),
+ case Prefix =:= {ok, <<45, 45, Boundary/bitstring>>} of
+ true ->
+ {ok, {multipart_body, <<>>, false, Data}};
+
+ false ->
+ parse_body_loop(Data, Boundary, <<>>)
+ end.
+
+-spec parse_multipart_body(bitstring(), binary()) -> {ok, multipart_body()} |
+ {error, nil}.
+parse_multipart_body(Data, Boundary) ->
+ _pipe = Boundary,
+ _pipe@1 = gleam_stdlib:identity(_pipe),
+ parse_body_with_bit_array(Data, _pipe@1).
+
+-spec method_from_dynamic(gleam@dynamic:dynamic_()) -> {ok, method()} |
+ {error, list(gleam@dynamic:decode_error())}.
+method_from_dynamic(Value) ->
+ case gleam_http_native:decode_method(Value) of
+ {ok, Method} ->
+ {ok, Method};
+
+ {error, _} ->
+ {error,
+ [{decode_error,
+ <<"HTTP method"/utf8>>,
+ gleam@dynamic:classify(Value),
+ []}]}
+ end.
+
+-spec parse_header_value(
+ bitstring(),
+ list({binary(), binary()}),
+ bitstring(),
+ bitstring()
+) -> {ok, multipart_headers()} | {error, nil}.
+parse_header_value(Data, Headers, Name, Value) ->
+ Size = erlang:byte_size(Data),
+ case Data of
+ _ when Size < 4 ->
+ _pipe@2 = fun(Data@1) -> _pipe = Data@1,
+ _pipe@1 = skip_whitespace(_pipe),
+ parse_header_value(_pipe@1, Headers, Name, Value) end,
+ more_please_headers(_pipe@2, Data);
+
+ <<13, 10, 13, 10, Data@2/binary>> ->
+ gleam@result:'try'(
+ gleam@bit_array:to_string(Name),
+ fun(Name@1) ->
+ gleam@result:map(
+ gleam@bit_array:to_string(Value),
+ fun(Value@1) ->
+ Headers@1 = gleam@list:reverse(
+ [{gleam@string:lowercase(Name@1), Value@1} |
+ Headers]
+ ),
+ {multipart_headers, Headers@1, Data@2}
+ end
+ )
+ end
+ );
+
+ <<13, 10, 32, Data@3/binary>> ->
+ parse_header_value(Data@3, Headers, Name, Value);
+
+ <<13, 10, 9, Data@3/binary>> ->
+ parse_header_value(Data@3, Headers, Name, Value);
+
+ <<13, 10, Data@4/binary>> ->
+ gleam@result:'try'(
+ gleam@bit_array:to_string(Name),
+ fun(Name@2) ->
+ gleam@result:'try'(
+ gleam@bit_array:to_string(Value),
+ fun(Value@2) ->
+ Headers@2 = [{gleam@string:lowercase(Name@2),
+ Value@2} |
+ Headers],
+ parse_header_name(Data@4, Headers@2, <<>>)
+ end
+ )
+ end
+ );
+
+ <<Char, Rest/binary>> ->
+ Value@3 = <<Value/bitstring, Char>>,
+ parse_header_value(Rest, Headers, Name, Value@3);
+
+ _ ->
+ {error, nil}
+ end.
+
+-spec parse_header_name(bitstring(), list({binary(), binary()}), bitstring()) -> {ok,
+ multipart_headers()} |
+ {error, nil}.
+parse_header_name(Data, Headers, Name) ->
+ case skip_whitespace(Data) of
+ <<58, Data@1/binary>> ->
+ _pipe = Data@1,
+ _pipe@1 = skip_whitespace(_pipe),
+ parse_header_value(_pipe@1, Headers, Name, <<>>);
+
+ <<Char, Data@2/binary>> ->
+ parse_header_name(Data@2, Headers, <<Name/bitstring, Char>>);
+
+ <<>> ->
+ more_please_headers(
+ fun(_capture) -> parse_header_name(_capture, Headers, Name) end,
+ Data
+ )
+ end.
+
+-spec do_parse_headers(bitstring()) -> {ok, multipart_headers()} | {error, nil}.
+do_parse_headers(Data) ->
+ case Data of
+ <<13, 10, 13, 10, Data@1/binary>> ->
+ {ok, {multipart_headers, [], Data@1}};
+
+ <<13, 10, Data@2/binary>> ->
+ parse_header_name(Data@2, [], <<>>);
+
+ <<13>> ->
+ more_please_headers(fun do_parse_headers/1, Data);
+
+ <<>> ->
+ more_please_headers(fun do_parse_headers/1, Data);
+
+ _ ->
+ {error, nil}
+ end.
+
+-spec parse_headers_after_prelude(bitstring(), bitstring()) -> {ok,
+ multipart_headers()} |
+ {error, nil}.
+parse_headers_after_prelude(Data, Boundary) ->
+ Dsize = erlang:byte_size(Data),
+ Bsize = erlang:byte_size(Boundary),
+ Required_size = Bsize + 4,
+ gleam@bool:guard(
+ Dsize < Required_size,
+ more_please_headers(
+ fun(_capture) -> parse_headers_after_prelude(_capture, Boundary) end,
+ Data
+ ),
+ fun() ->
+ gleam@result:'try'(
+ gleam_stdlib:bit_array_slice(Data, 0, Required_size - 2),
+ fun(Prefix) ->
+ gleam@result:'try'(
+ gleam_stdlib:bit_array_slice(Data, 2 + Bsize, 2),
+ fun(Second) ->
+ Desired = <<45, 45, Boundary/bitstring>>,
+ gleam@bool:guard(
+ Prefix /= Desired,
+ {error, nil},
+ fun() -> case Second =:= <<45, 45>> of
+ true ->
+ Rest_size = Dsize - Required_size,
+ gleam@result:map(
+ gleam_stdlib:bit_array_slice(
+ Data,
+ Required_size,
+ Rest_size
+ ),
+ fun(Data@1) ->
+ {multipart_headers,
+ [],
+ Data@1}
+ end
+ );
+
+ false ->
+ Start = Required_size - 2,
+ Rest_size@1 = (Dsize - Required_size)
+ + 2,
+ gleam@result:'try'(
+ gleam_stdlib:bit_array_slice(
+ Data,
+ Start,
+ Rest_size@1
+ ),
+ fun(Data@2) ->
+ do_parse_headers(Data@2)
+ end
+ )
+ end end
+ )
+ end
+ )
+ end
+ )
+ end
+ ).
+
+-spec skip_preamble(bitstring(), bitstring()) -> {ok, multipart_headers()} |
+ {error, nil}.
+skip_preamble(Data, Boundary) ->
+ Data_size = erlang:byte_size(Data),
+ Boundary_size = erlang:byte_size(Boundary),
+ Required = Boundary_size + 4,
+ case Data of
+ _ when Data_size < Required ->
+ more_please_headers(
+ fun(_capture) -> skip_preamble(_capture, Boundary) end,
+ Data
+ );
+
+ <<13, 10, 45, 45, Data@1/binary>> ->
+ case gleam_stdlib:bit_array_slice(Data@1, 0, Boundary_size) of
+ {ok, Prefix} when Prefix =:= Boundary ->
+ Start = Boundary_size,
+ Length = erlang:byte_size(Data@1) - Boundary_size,
+ gleam@result:'try'(
+ gleam_stdlib:bit_array_slice(Data@1, Start, Length),
+ fun(Rest) -> do_parse_headers(Rest) end
+ );
+
+ {ok, _} ->
+ skip_preamble(Data@1, Boundary);
+
+ {error, _} ->
+ {error, nil}
+ end;
+
+ <<_, Data@2/binary>> ->
+ skip_preamble(Data@2, Boundary)
+ end.
+
+-spec parse_multipart_headers(bitstring(), binary()) -> {ok,
+ multipart_headers()} |
+ {error, nil}.
+parse_multipart_headers(Data, Boundary) ->
+ Boundary@1 = gleam_stdlib:identity(Boundary),
+ Prefix = <<45, 45, Boundary@1/bitstring>>,
+ case gleam_stdlib:bit_array_slice(Data, 0, erlang:byte_size(Prefix)) =:= {ok,
+ Prefix} of
+ true ->
+ parse_headers_after_prelude(Data, Boundary@1);
+
+ false ->
+ skip_preamble(Data, Boundary@1)
+ end.
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.cache b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.cache
new file mode 100644
index 0000000..173ac86
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.cache_meta b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.cache_meta
new file mode 100644
index 0000000..1f65dce
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.erl b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.erl
new file mode 100644
index 0000000..9d6d13e
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@cookie.erl
@@ -0,0 +1,153 @@
+-module(gleam@http@cookie).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
+
+-export([defaults/1, set_header/3, parse/1]).
+-export_type([same_site_policy/0, attributes/0]).
+
+-type same_site_policy() :: lax | strict | none.
+
+-type attributes() :: {attributes,
+ gleam@option:option(integer()),
+ gleam@option:option(binary()),
+ gleam@option:option(binary()),
+ boolean(),
+ boolean(),
+ gleam@option:option(same_site_policy())}.
+
+-spec same_site_to_string(same_site_policy()) -> binary().
+same_site_to_string(Policy) ->
+ case Policy of
+ lax ->
+ <<"Lax"/utf8>>;
+
+ strict ->
+ <<"Strict"/utf8>>;
+
+ none ->
+ <<"None"/utf8>>
+ end.
+
+-spec defaults(gleam@http:scheme()) -> attributes().
+defaults(Scheme) ->
+ {attributes,
+ none,
+ none,
+ {some, <<"/"/utf8>>},
+ Scheme =:= https,
+ true,
+ {some, lax}}.
+
+-spec cookie_attributes_to_list(attributes()) -> list(list(binary())).
+cookie_attributes_to_list(Attributes) ->
+ {attributes, Max_age, Domain, Path, Secure, Http_only, Same_site} = Attributes,
+ _pipe = [case Max_age of
+ {some, 0} ->
+ {some, [<<"Expires=Thu, 01 Jan 1970 00:00:00 GMT"/utf8>>]};
+
+ _ ->
+ none
+ end, gleam@option:map(
+ Max_age,
+ fun(Max_age@1) ->
+ [<<"Max-Age="/utf8>>, gleam@int:to_string(Max_age@1)]
+ end
+ ), gleam@option:map(
+ Domain,
+ fun(Domain@1) -> [<<"Domain="/utf8>>, Domain@1] end
+ ), gleam@option:map(Path, fun(Path@1) -> [<<"Path="/utf8>>, Path@1] end), case Secure of
+ true ->
+ {some, [<<"Secure"/utf8>>]};
+
+ false ->
+ none
+ end, case Http_only of
+ true ->
+ {some, [<<"HttpOnly"/utf8>>]};
+
+ false ->
+ none
+ end, gleam@option:map(
+ Same_site,
+ fun(Same_site@1) ->
+ [<<"SameSite="/utf8>>, same_site_to_string(Same_site@1)]
+ end
+ )],
+ gleam@list:filter_map(
+ _pipe,
+ fun(_capture) -> gleam@option:to_result(_capture, nil) end
+ ).
+
+-spec set_header(binary(), binary(), attributes()) -> binary().
+set_header(Name, Value, Attributes) ->
+ _pipe = [[Name, <<"="/utf8>>, Value] |
+ cookie_attributes_to_list(Attributes)],
+ _pipe@1 = gleam@list:map(
+ _pipe,
+ fun(_capture) -> gleam@string:join(_capture, <<""/utf8>>) end
+ ),
+ gleam@string:join(_pipe@1, <<"; "/utf8>>).
+
+-spec check_token(binary()) -> {ok, nil} | {error, nil}.
+check_token(Token) ->
+ case gleam@string:pop_grapheme(Token) of
+ {error, nil} ->
+ {ok, nil};
+
+ {ok, {<<" "/utf8>>, _}} ->
+ {error, nil};
+
+ {ok, {<<"\t"/utf8>>, _}} ->
+ {error, nil};
+
+ {ok, {<<"\r"/utf8>>, _}} ->
+ {error, nil};
+
+ {ok, {<<"\n"/utf8>>, _}} ->
+ {error, nil};
+
+ {ok, {<<"\f"/utf8>>, _}} ->
+ {error, nil};
+
+ {ok, {_, Rest}} ->
+ check_token(Rest)
+ end.
+
+-spec parse(binary()) -> list({binary(), binary()}).
+parse(Cookie_string) ->
+ _assert_subject = gleam@regex:from_string(<<"[,;]"/utf8>>),
+ {ok, Re} = case _assert_subject of
+ {ok, _} -> _assert_subject;
+ _assert_fail ->
+ erlang:error(#{gleam_error => let_assert,
+ message => <<"Assertion pattern match failed"/utf8>>,
+ value => _assert_fail,
+ module => <<"gleam/http/cookie"/utf8>>,
+ function => <<"parse"/utf8>>,
+ line => 101})
+ end,
+ _pipe = gleam@regex:split(Re, Cookie_string),
+ gleam@list:filter_map(
+ _pipe,
+ fun(Pair) ->
+ case gleam@string:split_once(gleam@string:trim(Pair), <<"="/utf8>>) of
+ {ok, {<<""/utf8>>, _}} ->
+ {error, nil};
+
+ {ok, {Key, Value}} ->
+ Key@1 = gleam@string:trim(Key),
+ Value@1 = gleam@string:trim(Value),
+ gleam@result:then(
+ check_token(Key@1),
+ fun(_) ->
+ gleam@result:then(
+ check_token(Value@1),
+ fun(_) -> {ok, {Key@1, Value@1}} end
+ )
+ end
+ );
+
+ {error, nil} ->
+ {error, nil}
+ end
+ end
+ ).
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.cache b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.cache
new file mode 100644
index 0000000..cf9bcd7
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.cache_meta b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.cache_meta
new file mode 100644
index 0000000..2108b82
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.erl b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.erl
new file mode 100644
index 0000000..e41d548
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@request.erl
@@ -0,0 +1,202 @@
+-module(gleam@http@request).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
+
+-export([to_uri/1, from_uri/1, get_header/2, set_header/3, prepend_header/3, set_body/2, map/2, path_segments/1, get_query/1, set_query/2, set_method/2, new/0, to/1, set_scheme/2, set_host/2, set_port/2, set_path/2, set_cookie/3, get_cookies/1]).
+-export_type([request/1]).
+
+-type request(IAV) :: {request,
+ gleam@http:method(),
+ list({binary(), binary()}),
+ IAV,
+ gleam@http:scheme(),
+ binary(),
+ gleam@option:option(integer()),
+ binary(),
+ gleam@option:option(binary())}.
+
+-spec to_uri(request(any())) -> gleam@uri:uri().
+to_uri(Request) ->
+ {uri,
+ {some, gleam@http:scheme_to_string(erlang:element(5, Request))},
+ none,
+ {some, erlang:element(6, Request)},
+ erlang:element(7, Request),
+ erlang:element(8, Request),
+ erlang:element(9, Request),
+ none}.
+
+-spec from_uri(gleam@uri:uri()) -> {ok, request(binary())} | {error, nil}.
+from_uri(Uri) ->
+ gleam@result:then(
+ begin
+ _pipe = erlang:element(2, Uri),
+ _pipe@1 = gleam@option:unwrap(_pipe, <<""/utf8>>),
+ gleam@http:scheme_from_string(_pipe@1)
+ end,
+ fun(Scheme) ->
+ gleam@result:then(
+ begin
+ _pipe@2 = erlang:element(4, Uri),
+ gleam@option:to_result(_pipe@2, nil)
+ end,
+ fun(Host) ->
+ Req = {request,
+ get,
+ [],
+ <<""/utf8>>,
+ Scheme,
+ Host,
+ erlang:element(5, Uri),
+ erlang:element(6, Uri),
+ erlang:element(7, Uri)},
+ {ok, Req}
+ end
+ )
+ end
+ ).
+
+-spec get_header(request(any()), binary()) -> {ok, binary()} | {error, nil}.
+get_header(Request, Key) ->
+ gleam@list:key_find(erlang:element(3, Request), gleam@string:lowercase(Key)).
+
+-spec set_header(request(IBF), binary(), binary()) -> request(IBF).
+set_header(Request, Key, Value) ->
+ Headers = gleam@list:key_set(
+ erlang:element(3, Request),
+ gleam@string:lowercase(Key),
+ Value
+ ),
+ erlang:setelement(3, Request, Headers).
+
+-spec prepend_header(request(IBI), binary(), binary()) -> request(IBI).
+prepend_header(Request, Key, Value) ->
+ Headers = [{gleam@string:lowercase(Key), Value} |
+ erlang:element(3, Request)],
+ erlang:setelement(3, Request, Headers).
+
+-spec set_body(request(any()), IBN) -> request(IBN).
+set_body(Req, Body) ->
+ {request, Method, Headers, _, Scheme, Host, Port, Path, Query} = Req,
+ {request, Method, Headers, Body, Scheme, Host, Port, Path, Query}.
+
+-spec map(request(IBP), fun((IBP) -> IBR)) -> request(IBR).
+map(Request, Transform) ->
+ _pipe = erlang:element(4, Request),
+ _pipe@1 = Transform(_pipe),
+ set_body(Request, _pipe@1).
+
+-spec path_segments(request(any())) -> list(binary()).
+path_segments(Request) ->
+ _pipe = erlang:element(8, Request),
+ gleam@uri:path_segments(_pipe).
+
+-spec get_query(request(any())) -> {ok, list({binary(), binary()})} |
+ {error, nil}.
+get_query(Request) ->
+ case erlang:element(9, Request) of
+ {some, Query_string} ->
+ gleam@uri:parse_query(Query_string);
+
+ none ->
+ {ok, []}
+ end.
+
+-spec set_query(request(ICB), list({binary(), binary()})) -> request(ICB).
+set_query(Req, Query) ->
+ Pair = fun(T) ->
+ gleam@string_builder:from_strings(
+ [erlang:element(1, T), <<"="/utf8>>, erlang:element(2, T)]
+ )
+ end,
+ Query@1 = begin
+ _pipe = Query,
+ _pipe@1 = gleam@list:map(_pipe, Pair),
+ _pipe@2 = gleam@list:intersperse(
+ _pipe@1,
+ gleam@string_builder:from_string(<<"&"/utf8>>)
+ ),
+ _pipe@3 = gleam@string_builder:concat(_pipe@2),
+ _pipe@4 = gleam@string_builder:to_string(_pipe@3),
+ {some, _pipe@4}
+ end,
+ erlang:setelement(9, Req, Query@1).
+
+-spec set_method(request(ICF), gleam@http:method()) -> request(ICF).
+set_method(Req, Method) ->
+ erlang:setelement(2, Req, Method).
+
+-spec new() -> request(binary()).
+new() ->
+ {request,
+ get,
+ [],
+ <<""/utf8>>,
+ https,
+ <<"localhost"/utf8>>,
+ none,
+ <<""/utf8>>,
+ none}.
+
+-spec to(binary()) -> {ok, request(binary())} | {error, nil}.
+to(Url) ->
+ _pipe = Url,
+ _pipe@1 = gleam@uri:parse(_pipe),
+ gleam@result:then(_pipe@1, fun from_uri/1).
+
+-spec set_scheme(request(ICM), gleam@http:scheme()) -> request(ICM).
+set_scheme(Req, Scheme) ->
+ erlang:setelement(5, Req, Scheme).
+
+-spec set_host(request(ICP), binary()) -> request(ICP).
+set_host(Req, Host) ->
+ erlang:setelement(6, Req, Host).
+
+-spec set_port(request(ICS), integer()) -> request(ICS).
+set_port(Req, Port) ->
+ erlang:setelement(7, Req, {some, Port}).
+
+-spec set_path(request(ICV), binary()) -> request(ICV).
+set_path(Req, Path) ->
+ erlang:setelement(8, Req, Path).
+
+-spec set_cookie(request(ICY), binary(), binary()) -> request(ICY).
+set_cookie(Req, Name, Value) ->
+ New_cookie_string = gleam@string:join([Name, Value], <<"="/utf8>>),
+ {Cookies_string@2, Headers@1} = case gleam@list:key_pop(
+ erlang:element(3, Req),
+ <<"cookie"/utf8>>
+ ) of
+ {ok, {Cookies_string, Headers}} ->
+ Cookies_string@1 = gleam@string:join(
+ [Cookies_string, New_cookie_string],
+ <<"; "/utf8>>
+ ),
+ {Cookies_string@1, Headers};
+
+ {error, nil} ->
+ {New_cookie_string, erlang:element(3, Req)}
+ end,
+ erlang:setelement(
+ 3,
+ Req,
+ [{<<"cookie"/utf8>>, Cookies_string@2} | Headers@1]
+ ).
+
+-spec get_cookies(request(any())) -> list({binary(), binary()}).
+get_cookies(Req) ->
+ {request, _, Headers, _, _, _, _, _, _} = Req,
+ _pipe = Headers,
+ _pipe@1 = gleam@list:filter_map(
+ _pipe,
+ fun(Header) ->
+ {Name, Value} = Header,
+ case Name of
+ <<"cookie"/utf8>> ->
+ {ok, gleam@http@cookie:parse(Value)};
+
+ _ ->
+ {error, nil}
+ end
+ end
+ ),
+ gleam@list:flatten(_pipe@1).
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.cache b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.cache
new file mode 100644
index 0000000..5656963
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.cache_meta b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.cache_meta
new file mode 100644
index 0000000..1f05041
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.erl b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.erl
new file mode 100644
index 0000000..300726a
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@response.erl
@@ -0,0 +1,97 @@
+-module(gleam@http@response).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
+
+-export([new/1, get_header/2, set_header/3, prepend_header/3, set_body/2, try_map/2, map/2, redirect/1, get_cookies/1, set_cookie/4, expire_cookie/3]).
+-export_type([response/1]).
+
+-type response(HXJ) :: {response, integer(), list({binary(), binary()}), HXJ}.
+
+-spec new(integer()) -> response(binary()).
+new(Status) ->
+ {response, Status, [], <<""/utf8>>}.
+
+-spec get_header(response(any()), binary()) -> {ok, binary()} | {error, nil}.
+get_header(Response, Key) ->
+ gleam@list:key_find(
+ erlang:element(3, Response),
+ gleam@string:lowercase(Key)
+ ).
+
+-spec set_header(response(HXY), binary(), binary()) -> response(HXY).
+set_header(Response, Key, Value) ->
+ Headers = gleam@list:key_set(
+ erlang:element(3, Response),
+ gleam@string:lowercase(Key),
+ Value
+ ),
+ erlang:setelement(3, Response, Headers).
+
+-spec prepend_header(response(HYB), binary(), binary()) -> response(HYB).
+prepend_header(Response, Key, Value) ->
+ Headers = [{gleam@string:lowercase(Key), Value} |
+ erlang:element(3, Response)],
+ erlang:setelement(3, Response, Headers).
+
+-spec set_body(response(any()), HYG) -> response(HYG).
+set_body(Response, Body) ->
+ {response, Status, Headers, _} = Response,
+ {response, Status, Headers, Body}.
+
+-spec try_map(response(HXK), fun((HXK) -> {ok, HXM} | {error, HXN})) -> {ok,
+ response(HXM)} |
+ {error, HXN}.
+try_map(Response, Transform) ->
+ gleam@result:then(
+ Transform(erlang:element(4, Response)),
+ fun(Body) -> {ok, set_body(Response, Body)} end
+ ).
+
+-spec map(response(HYI), fun((HYI) -> HYK)) -> response(HYK).
+map(Response, Transform) ->
+ _pipe = erlang:element(4, Response),
+ _pipe@1 = Transform(_pipe),
+ set_body(Response, _pipe@1).
+
+-spec redirect(binary()) -> response(binary()).
+redirect(Uri) ->
+ {response,
+ 303,
+ [{<<"location"/utf8>>, Uri}],
+ gleam@string:append(<<"You are being redirected to "/utf8>>, Uri)}.
+
+-spec get_cookies(response(any())) -> list({binary(), binary()}).
+get_cookies(Resp) ->
+ {response, _, Headers, _} = Resp,
+ _pipe = Headers,
+ _pipe@1 = gleam@list:filter_map(
+ _pipe,
+ fun(Header) ->
+ {Name, Value} = Header,
+ case Name of
+ <<"set-cookie"/utf8>> ->
+ {ok, gleam@http@cookie:parse(Value)};
+
+ _ ->
+ {error, nil}
+ end
+ end
+ ),
+ gleam@list:flatten(_pipe@1).
+
+-spec set_cookie(
+ response(HYP),
+ binary(),
+ binary(),
+ gleam@http@cookie:attributes()
+) -> response(HYP).
+set_cookie(Response, Name, Value, Attributes) ->
+ prepend_header(
+ Response,
+ <<"set-cookie"/utf8>>,
+ gleam@http@cookie:set_header(Name, Value, Attributes)
+ ).
+
+-spec expire_cookie(response(HYS), binary(), gleam@http@cookie:attributes()) -> response(HYS).
+expire_cookie(Response, Name, Attributes) ->
+ Attrs = erlang:setelement(2, Attributes, {some, 0}),
+ set_cookie(Response, Name, <<""/utf8>>, Attrs).
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.cache b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.cache
new file mode 100644
index 0000000..2bdc561
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.cache_meta b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.cache_meta
new file mode 100644
index 0000000..c0222d6
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.erl b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.erl
new file mode 100644
index 0000000..7aa0ed5
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam@http@service.erl
@@ -0,0 +1,82 @@
+-module(gleam@http@service).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
+
+-export([map_response_body/2, prepend_response_header/3, method_override/1]).
+
+-spec map_response_body(
+ fun((gleam@http@request:request(IIL)) -> gleam@http@response:response(IIM)),
+ fun((IIM) -> IIP)
+) -> fun((gleam@http@request:request(IIL)) -> gleam@http@response:response(IIP)).
+map_response_body(Service, Mapper) ->
+ fun(Req) -> _pipe = Req,
+ _pipe@1 = Service(_pipe),
+ gleam@http@response:map(_pipe@1, Mapper) end.
+
+-spec prepend_response_header(
+ fun((gleam@http@request:request(IIS)) -> gleam@http@response:response(IIT)),
+ binary(),
+ binary()
+) -> fun((gleam@http@request:request(IIS)) -> gleam@http@response:response(IIT)).
+prepend_response_header(Service, Key, Value) ->
+ fun(Req) -> _pipe = Req,
+ _pipe@1 = Service(_pipe),
+ gleam@http@response:prepend_header(_pipe@1, Key, Value) end.
+
+-spec ensure_post(gleam@http@request:request(IIY)) -> {ok,
+ gleam@http@request:request(IIY)} |
+ {error, nil}.
+ensure_post(Req) ->
+ case erlang:element(2, Req) of
+ post ->
+ {ok, Req};
+
+ _ ->
+ {error, nil}
+ end.
+
+-spec get_override_method(gleam@http@request:request(any())) -> {ok,
+ gleam@http:method()} |
+ {error, nil}.
+get_override_method(Request) ->
+ gleam@result:then(
+ gleam@http@request:get_query(Request),
+ fun(Query_params) ->
+ gleam@result:then(
+ gleam@list:key_find(Query_params, <<"_method"/utf8>>),
+ fun(Method) ->
+ gleam@result:then(
+ gleam@http:parse_method(Method),
+ fun(Method@1) -> case Method@1 of
+ put ->
+ {ok, Method@1};
+
+ patch ->
+ {ok, Method@1};
+
+ delete ->
+ {ok, Method@1};
+
+ _ ->
+ {error, nil}
+ end end
+ )
+ end
+ )
+ end
+ ).
+
+-spec method_override(
+ fun((gleam@http@request:request(IJF)) -> gleam@http@response:response(IJG))
+) -> fun((gleam@http@request:request(IJF)) -> gleam@http@response:response(IJG)).
+method_override(Service) ->
+ fun(Request) -> _pipe = Request,
+ _pipe@1 = ensure_post(_pipe),
+ _pipe@2 = gleam@result:then(_pipe@1, fun get_override_method/1),
+ _pipe@3 = gleam@result:map(
+ _pipe@2,
+ fun(_capture) ->
+ gleam@http@request:set_method(Request, _capture)
+ end
+ ),
+ _pipe@4 = gleam@result:unwrap(_pipe@3, Request),
+ Service(_pipe@4) end.
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam_http_native.erl b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam_http_native.erl
new file mode 100644
index 0000000..bb499bb
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam_http_native.erl
@@ -0,0 +1,88 @@
+-module(gleam_http_native).
+-export([decode_method/1]).
+
+decode_method(Term) ->
+ case Term of
+ "connect" -> {ok, connect};
+ "delete" -> {ok, delete};
+ "get" -> {ok, get};
+ "head" -> {ok, head};
+ "options" -> {ok, options};
+ "patch" -> {ok, patch};
+ "post" -> {ok, post};
+ "put" -> {ok, put};
+ "trace" -> {ok, trace};
+ "CONNECT" -> {ok, connect};
+ "DELETE" -> {ok, delete};
+ "GET" -> {ok, get};
+ "HEAD" -> {ok, head};
+ "OPTIONS" -> {ok, options};
+ "PATCH" -> {ok, patch};
+ "POST" -> {ok, post};
+ "PUT" -> {ok, put};
+ "TRACE" -> {ok, trace};
+ "Connect" -> {ok, connect};
+ "Delete" -> {ok, delete};
+ "Get" -> {ok, get};
+ "Head" -> {ok, head};
+ "Options" -> {ok, options};
+ "Patch" -> {ok, patch};
+ "Post" -> {ok, post};
+ "Put" -> {ok, put};
+ "Trace" -> {ok, trace};
+ 'connect' -> {ok, connect};
+ 'delete' -> {ok, delete};
+ 'get' -> {ok, get};
+ 'head' -> {ok, head};
+ 'options' -> {ok, options};
+ 'patch' -> {ok, patch};
+ 'post' -> {ok, post};
+ 'put' -> {ok, put};
+ 'trace' -> {ok, trace};
+ 'CONNECT' -> {ok, connect};
+ 'DELETE' -> {ok, delete};
+ 'GET' -> {ok, get};
+ 'HEAD' -> {ok, head};
+ 'OPTIONS' -> {ok, options};
+ 'PATCH' -> {ok, patch};
+ 'POST' -> {ok, post};
+ 'PUT' -> {ok, put};
+ 'TRACE' -> {ok, trace};
+ 'Connect' -> {ok, connect};
+ 'Delete' -> {ok, delete};
+ 'Get' -> {ok, get};
+ 'Head' -> {ok, head};
+ 'Options' -> {ok, options};
+ 'Patch' -> {ok, patch};
+ 'Post' -> {ok, post};
+ 'Put' -> {ok, put};
+ 'Trace' -> {ok, trace};
+ <<"connect">> -> {ok, connect};
+ <<"delete">> -> {ok, delete};
+ <<"get">> -> {ok, get};
+ <<"head">> -> {ok, head};
+ <<"options">> -> {ok, options};
+ <<"patch">> -> {ok, patch};
+ <<"post">> -> {ok, post};
+ <<"put">> -> {ok, put};
+ <<"trace">> -> {ok, trace};
+ <<"CONNECT">> -> {ok, connect};
+ <<"DELETE">> -> {ok, delete};
+ <<"GET">> -> {ok, get};
+ <<"HEAD">> -> {ok, head};
+ <<"OPTIONS">> -> {ok, options};
+ <<"PATCH">> -> {ok, patch};
+ <<"POST">> -> {ok, post};
+ <<"PUT">> -> {ok, put};
+ <<"TRACE">> -> {ok, trace};
+ <<"Connect">> -> {ok, connect};
+ <<"Delete">> -> {ok, delete};
+ <<"Get">> -> {ok, get};
+ <<"Head">> -> {ok, head};
+ <<"Options">> -> {ok, options};
+ <<"Patch">> -> {ok, patch};
+ <<"Post">> -> {ok, post};
+ <<"Put">> -> {ok, put};
+ <<"Trace">> -> {ok, trace};
+ _ -> {error, nil}
+ end.
diff --git a/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam_http_native.mjs b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam_http_native.mjs
new file mode 100644
index 0000000..c871a8b
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/_gleam_artefacts/gleam_http_native.mjs
@@ -0,0 +1,38 @@
+import { Ok, Error } from "./gleam.mjs";
+import {
+ Get,
+ Post,
+ Head,
+ Put,
+ Delete,
+ Trace,
+ Connect,
+ Options,
+ Patch,
+} from "./gleam/http.mjs";
+
+export function decode_method(value) {
+ try {
+ switch (value.toLowerCase()) {
+ case "get":
+ return new Ok(new Get());
+ case "post":
+ return new Ok(new Post());
+ case "head":
+ return new Ok(new Head());
+ case "put":
+ return new Ok(new Put());
+ case "delete":
+ return new Ok(new Delete());
+ case "trace":
+ return new Ok(new Trace());
+ case "connect":
+ return new Ok(new Connect());
+ case "options":
+ return new Ok(new Options());
+ case "patch":
+ return new Ok(new Patch());
+ }
+ } catch {}
+ return new Error(undefined);
+}
diff --git a/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http.beam b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http.beam
new file mode 100644
index 0000000..39142e6
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@cookie.beam b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@cookie.beam
new file mode 100644
index 0000000..905fe68
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@cookie.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@request.beam b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@request.beam
new file mode 100644
index 0000000..f499969
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@request.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@response.beam b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@response.beam
new file mode 100644
index 0000000..1554f40
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@response.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@service.beam b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@service.beam
new file mode 100644
index 0000000..aa271f1
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam@http@service.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/ebin/gleam_http.app b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam_http.app
new file mode 100644
index 0000000..5f55c6f
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam_http.app
@@ -0,0 +1,7 @@
+{application, gleam_http, [
+ {vsn, "3.5.2"},
+ {applications, [gleam_stdlib]},
+ {description, "Types and functions for Gleam HTTP clients and servers"},
+ {modules, []},
+ {registered, []}
+]}.
diff --git a/aoc2023/build/dev/erlang/gleam_http/ebin/gleam_http_native.beam b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam_http_native.beam
new file mode 100644
index 0000000..0b5e282
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/ebin/gleam_http_native.beam
Binary files differ
diff --git a/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@cookie_Attributes.hrl b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@cookie_Attributes.hrl
new file mode 100644
index 0000000..78a7d02
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@cookie_Attributes.hrl
@@ -0,0 +1,8 @@
+-record(attributes, {
+ max_age :: gleam@option:option(integer()),
+ domain :: gleam@option:option(binary()),
+ path :: gleam@option:option(binary()),
+ secure :: boolean(),
+ http_only :: boolean(),
+ same_site :: gleam@option:option(gleam@http@cookie:same_site_policy())
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@request_Request.hrl b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@request_Request.hrl
new file mode 100644
index 0000000..c8bbae6
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@request_Request.hrl
@@ -0,0 +1,10 @@
+-record(request, {
+ method :: gleam@http:method(),
+ headers :: list({binary(), binary()}),
+ body :: any(),
+ scheme :: gleam@http:scheme(),
+ host :: binary(),
+ port :: gleam@option:option(integer()),
+ path :: binary(),
+ 'query' :: gleam@option:option(binary())
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@response_Response.hrl b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@response_Response.hrl
new file mode 100644
index 0000000..ba6f077
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http@response_Response.hrl
@@ -0,0 +1,5 @@
+-record(response, {
+ status :: integer(),
+ headers :: list({binary(), binary()}),
+ body :: any()
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MoreRequiredForBody.hrl b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MoreRequiredForBody.hrl
new file mode 100644
index 0000000..abd56dd
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MoreRequiredForBody.hrl
@@ -0,0 +1,5 @@
+-record(more_required_for_body, {
+ chunk :: bitstring(),
+ continuation :: fun((bitstring()) -> {ok, gleam@http:multipart_body()} |
+ {error, nil})
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MoreRequiredForHeaders.hrl b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MoreRequiredForHeaders.hrl
new file mode 100644
index 0000000..43729c1
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MoreRequiredForHeaders.hrl
@@ -0,0 +1,4 @@
+-record(more_required_for_headers, {
+ continuation :: fun((bitstring()) -> {ok, gleam@http:multipart_headers()} |
+ {error, nil})
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MultipartBody.hrl b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MultipartBody.hrl
new file mode 100644
index 0000000..4521591
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MultipartBody.hrl
@@ -0,0 +1,5 @@
+-record(multipart_body, {
+ chunk :: bitstring(),
+ done :: boolean(),
+ remaining :: bitstring()
+}).
diff --git a/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MultipartHeaders.hrl b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MultipartHeaders.hrl
new file mode 100644
index 0000000..d9fca5c
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_http/include/gleam@http_MultipartHeaders.hrl
@@ -0,0 +1,4 @@
+-record(multipart_headers, {
+ headers :: list({binary(), binary()}),
+ remaining :: bitstring()
+}).