Current section

Files

Jump to
dream src dream@http@params.erl
Raw

src/dream@http@params.erl

-module(dream@http@params).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream/http/params.gleam").
-export([require_int/2, require_string/2, require_form/1, require_field/2, require_field_int/2, field_optional/2]).
-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(
" Parameter validation and extraction utilities\n"
"\n"
" This module provides safe parameter extraction from HTTP requests,\n"
" returning Result types with dream.Error instead of crashing on missing or invalid data.\n"
"\n"
" Use these helpers to validate path parameters and form data in controllers,\n"
" then pipe the results through your business logic using gleam/result.\n"
).
-file("src/dream/http/params.gleam", 113).
-spec parse_int_field(binary(), binary()) -> {ok, integer()} |
{error, dream@http@error:error()}.
parse_int_field(Value, Name) ->
case gleam_stdlib:parse_int(Value) of
{ok, I} ->
{ok, I};
{error, _} ->
{error,
{bad_request,
<<<<"Field '"/utf8, Name/binary>>/binary,
"' must be an integer"/utf8>>}}
end.
-file("src/dream/http/params.gleam", 120).
-spec result_string_to_error({ok, ADOU} | {error, binary()}) -> {ok, ADOU} |
{error, dream@http@error:error()}.
result_string_to_error(Result) ->
case Result of
{ok, Value} ->
{ok, Value};
{error, Msg} ->
{error, {bad_request, Msg}}
end.
-file("src/dream/http/params.gleam", 32).
?DOC(
" Require a path parameter as an integer\n"
"\n"
" Returns a Result with dream.Error if the parameter is missing\n"
" or cannot be converted to an integer.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" // Using with gleam/result pipeline\n"
" let result = {\n"
" use id <- result.try(params.require_int(request, \"id\"))\n"
" // ... rest of logic with id : Int\n"
" }\n"
" ```\n"
).
-spec require_int(dream@http@request:request(), binary()) -> {ok, integer()} |
{error, dream@http@error:error()}.
require_int(Req, Name) ->
_pipe = dream@http@request:get_int_param(Req, Name),
result_string_to_error(_pipe).
-file("src/dream/http/params.gleam", 47).
?DOC(
" Require a path parameter as a string\n"
"\n"
" Returns a Result with dream.Error if the parameter is missing.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" use name <- result.try(params.require_string(request, \"name\"))\n"
" // ... rest of logic with name : String\n"
" ```\n"
).
-spec require_string(dream@http@request:request(), binary()) -> {ok, binary()} |
{error, dream@http@error:error()}.
require_string(Req, Name) ->
_pipe = dream@http@request:get_string_param(Req, Name),
result_string_to_error(_pipe).
-file("src/dream/http/params.gleam", 192).
-spec decode_url_component(binary()) -> binary().
decode_url_component(Component) ->
With_spaces = gleam@string:replace(Component, <<"+"/utf8>>, <<" "/utf8>>),
case gleam_stdlib:percent_decode(With_spaces) of
{ok, Decoded} ->
Decoded;
{error, _} ->
With_spaces
end.
-file("src/dream/http/params.gleam", 177).
-spec parse_form_pair(binary()) -> gleam@option:option({binary(), binary()}).
parse_form_pair(Pair) ->
case gleam@string:split(Pair, <<"="/utf8>>) of
[Key, Value] ->
Decoded_key = decode_url_component(Key),
Decoded_value = decode_url_component(Value),
{some, {Decoded_key, Decoded_value}};
[Key@1] ->
Decoded_key@1 = decode_url_component(Key@1),
{some, {Decoded_key@1, <<""/utf8>>}};
_ ->
none
end.
-file("src/dream/http/params.gleam", 167).
-spec add_parsed_pair(binary(), list({binary(), binary()})) -> list({binary(),
binary()}).
add_parsed_pair(Pair, Rest_parsed) ->
case parse_form_pair(Pair) of
{some, Kv} ->
[Kv | Rest_parsed];
none ->
Rest_parsed
end.
-file("src/dream/http/params.gleam", 157).
-spec parse_form_pairs(list(binary())) -> list({binary(), binary()}).
parse_form_pairs(Pairs) ->
case Pairs of
[] ->
[];
[Pair | Rest] ->
Rest_parsed = parse_form_pairs(Rest),
add_parsed_pair(Pair, Rest_parsed)
end.
-file("src/dream/http/params.gleam", 150).
-spec parse_form_body(binary()) -> list({binary(), binary()}).
parse_form_body(Body) ->
case Body of
<<""/utf8>> ->
[];
_ ->
parse_form_pairs(gleam@string:split(Body, <<"&"/utf8>>))
end.
-file("src/dream/http/params.gleam", 63).
?DOC(
" Require and parse form data from request body\n"
"\n"
" Returns a Result containing the parsed form data as key-value pairs.\n"
" Returns an error if the body is empty or invalid.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" use form <- result.try(params.require_form(request))\n"
" use title <- result.try(params.require_field(form, \"title\"))\n"
" ```\n"
).
-spec require_form(dream@http@request:request()) -> {ok,
list({binary(), binary()})} |
{error, dream@http@error:error()}.
require_form(Req) ->
case erlang:element(11, Req) of
<<""/utf8>> ->
{error, {bad_request, <<"Request body is empty"/utf8>>}};
Body ->
{ok, parse_form_body(Body)}
end.
-file("src/dream/http/params.gleam", 203).
-spec get_form_field(list({binary(), binary()}), binary()) -> gleam@option:option(binary()).
get_form_field(Form_data, Name) ->
_pipe = gleam@list:key_find(Form_data, Name),
gleam@option:from_result(_pipe).
-file("src/dream/http/params.gleam", 80).
?DOC(
" Require a field from form data\n"
"\n"
" Returns an error if the field is missing or empty.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" use form <- result.try(params.require_form(request))\n"
" use title <- result.try(params.require_field(form, \"title\"))\n"
" ```\n"
).
-spec require_field(list({binary(), binary()}), binary()) -> {ok, binary()} |
{error, dream@http@error:error()}.
require_field(Form, Name) ->
case get_form_field(Form, Name) of
{some, <<""/utf8>>} ->
{error,
{bad_request,
<<<<"Field '"/utf8, Name/binary>>/binary,
"' cannot be empty"/utf8>>}};
{some, Value} ->
{ok, Value};
none ->
{error,
{bad_request, <<"Missing required field: "/utf8, Name/binary>>}}
end.
-file("src/dream/http/params.gleam", 102).
?DOC(
" Require a field from form data as an integer\n"
"\n"
" Returns an error if the field is missing, empty, or not a valid integer.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" use form <- result.try(params.require_form(request))\n"
" use priority <- result.try(params.require_field_int(form, \"priority\"))\n"
" ```\n"
).
-spec require_field_int(list({binary(), binary()}), binary()) -> {ok, integer()} |
{error, dream@http@error:error()}.
require_field_int(Form, Name) ->
Result = begin
gleam@result:'try'(
require_field(Form, Name),
fun(Value) -> parse_int_field(Value, Name) end
)
end,
Result.
-file("src/dream/http/params.gleam", 137).
?DOC(
" Extract an optional field from form data\n"
"\n"
" Returns None if the field is missing or empty, Some(value) otherwise.\n"
" This never returns an error - use this for truly optional fields.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let description = params.field_optional(form, \"description\")\n"
" ```\n"
).
-spec field_optional(list({binary(), binary()}), binary()) -> gleam@option:option(binary()).
field_optional(Form, Name) ->
case get_form_field(Form, Name) of
{some, <<""/utf8>>} ->
none;
{some, Value} ->
{some, Value};
none ->
none
end.