Current section

Files

Jump to
formz src formz@validation.erl
Raw

src/formz@validation.erl

-module(formz@validation).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export(['and'/2, email/1, int/1, number/1, list_item_by_index/1, non_empty_string/1, on/1, replace_error/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.
-file("src/formz/validation.gleam", 28).
?DOC(
" Chain validations together.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let is_even = fn(num) {\n"
" case num % 2 == 0 {\n"
" True -> Ok(num)\n"
" False -> Error(\"must be even\")\n"
" }\n"
" }\n"
" let check = and(int, is_even)\n"
"\n"
" check(\"2\")\n"
" # -> Ok(2)\n"
"\n"
" check(\"hi\")\n"
" # -> Error(\"must be a whole number\")\n"
"\n"
" check(\"1\")\n"
" # -> Error(\"must be even\")\n"
).
-spec 'and'(
fun((HOX) -> {ok, HOY} | {error, binary()}),
fun((HOY) -> {ok, HPB} | {error, binary()})
) -> fun((HOX) -> {ok, HPB} | {error, binary()}).
'and'(Previous, Next) ->
fun(Data) -> case Previous(Data) of
{ok, Value} ->
Next(Value);
{error, Error} ->
{error, Error}
end end.
-file("src/formz/validation.gleam", 61).
?DOC(
" Parse the input as a String that looks like an email address, i.e. it\n"
" contains an `@` character, with at least one other character on either\n"
" side\n"
"\n"
" (this behavior more closely matches what the browser does than just\n"
" checking for an `@`).\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" email(\"hello@example.com\")\n"
" # -> Ok(\"hello@example.com\")\n"
" ```\n"
" ```gleam\n"
" email(\"@\")\n"
" # -> Error(\"Must be an email address\")\n"
" ```\n"
" ```gleam\n"
" email(\"hello\")\n"
" # -> Error(\"Must be an email address\")\n"
" ```\n"
).
-spec email(binary()) -> {ok, binary()} | {error, binary()}.
email(Input) ->
case begin
_pipe = Input,
gleam@string:trim(_pipe)
end of
<<""/utf8>> ->
{error, <<"is required"/utf8>>};
Trimmed ->
case begin
_pipe@1 = Trimmed,
_pipe@2 = gleam@string:split(_pipe@1, <<"@"/utf8>>),
gleam@list:map(_pipe@2, fun gleam@string:length/1)
end of
[Before, After] when (Before > 0) andalso (After > 0) ->
{ok, Trimmed};
_ ->
{error, <<"must be an email address"/utf8>>}
end
end.
-file("src/formz/validation.gleam", 117).
?DOC(
" Parse the input as an int.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" int(\"1\")\n"
" # -> Ok(1)\n"
" ```\n"
"\n"
" ```gleam\n"
" int(\"3.4\")\n"
" # -> Error(\"Must be a whole number\")\n"
" ```\n"
" ```gleam\n"
" int(\"hello\")\n"
" # -> Error(\"Must be a whole number\")\n"
" ```\n"
).
-spec int(binary()) -> {ok, integer()} | {error, binary()}.
int(Str) ->
_pipe = Str,
_pipe@1 = gleam@string:trim(_pipe),
_pipe@2 = gleam@int:parse(_pipe@1),
gleam@result:replace_error(_pipe@2, <<"must be a whole number"/utf8>>).
-file("src/formz/validation.gleam", 91).
?DOC(
" Parse the input as a float. this is forgiving and will also parse\n"
" ints into floats.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" number(\"1\")\n"
" # -> Ok(1.0)\n"
" ```\n"
"\n"
" ```gleam\n"
" number(\"3.4\")\n"
" # -> Ok(3.4)\n"
" ```\n"
" ```gleam\n"
" number(\"hello\")\n"
" # -> Error(\"Must be a number\")\n"
" ```\n"
).
-spec number(binary()) -> {ok, float()} | {error, binary()}.
number(Str) ->
Str@1 = gleam@string:trim(Str),
_pipe@1 = case gleam@float:parse(Str@1) of
{ok, Value} ->
{ok, Value};
{error, _} ->
_pipe = gleam@int:parse(Str@1),
gleam@result:map(_pipe, fun gleam@int:to_float/1)
end,
gleam@result:replace_error(_pipe@1, <<"must be a number"/utf8>>).
-file("src/formz/validation.gleam", 144).
?DOC(
" Validates that the input is one from a list of allowed values. Takes a list\n"
" of Gleam values that can be chosen. This uses the index of the item to\n"
" find the desired value.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" enum([\"One\",\"Two\",\"Three\"])(\"1\")\n"
" # -> Ok(\"Two\")\n"
" ```\n"
"\n"
" ```gleam\n"
" enum([True, False])(\"42\")\n"
" # -> Error(\"must be an item in list\")\n"
" ```\n"
"\n"
" ```gleam\n"
" enum([True, False])(\"ok\")\n"
" # -> Error(\"must be an item in list\")\n"
" ```\n"
).
-spec list_item_by_index(list(HPM)) -> fun((binary()) -> {ok, HPM} |
{error, binary()}).
list_item_by_index(Variants) ->
fun(Str) -> _pipe = Variants,
_pipe@1 = gleam@list:index_map(
_pipe,
fun(Val, I) -> {gleam@int:to_string(I), Val} end
),
_pipe@2 = gleam@list:key_find(_pipe@1, Str),
gleam@result:replace_error(_pipe@2, <<"must be an item in list"/utf8>>) end.
-file("src/formz/validation.gleam", 168).
?DOC(
" Trim and leave the input as it is, but verify it is non-empty.\n"
"\n"
" ```gleam\n"
" non_empty_string(\"hello\")\n"
" # -> Ok(\"hello\")\n"
" ```\n"
"\n"
" ```gleam\n"
" non_empty_string(\" \")\n"
" # -> Error(\"is required\")\n"
" ```\n"
).
-spec non_empty_string(binary()) -> {ok, binary()} | {error, binary()}.
non_empty_string(Str) ->
case gleam@string:trim(Str) of
<<""/utf8>> ->
{error, <<"is required"/utf8>>};
Trimmed ->
{ok, Trimmed}
end.
-file("src/formz/validation.gleam", 195).
?DOC(
" Parse the input as a boolean, where only \"on\" is True and allowed.\n"
" All other values are an error. This is useful for HTML checkboxes, which\n"
" the browser sends the empty string if unchecked, and `\"on\"` if checked.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" on(\"on\")\n"
" # -> Ok(True)\n"
" ```\n"
"\n"
" ```gleam\n"
" on(\"\")\n"
" # -> Error(\"is required\")\n"
" ```\n"
"\n"
" ```gleam\n"
" on(\"hi\")\n"
" # -> Error(\"is required\")\n"
" ```\n"
).
-spec on(binary()) -> {ok, boolean()} | {error, binary()}.
on(Val) ->
case Val of
<<"on"/utf8>> ->
{ok, true};
_ ->
{error, <<"must be on"/utf8>>}
end.
-file("src/formz/validation.gleam", 204).
?DOC(
" Replace the error message of a validation with a new one. Most of the built-in\n"
" error messages are pretty rudimentary.\n"
).
-spec replace_error(fun((HPU) -> {ok, HPV} | {error, binary()}), binary()) -> fun((HPU) -> {ok,
HPV} |
{error, binary()}).
replace_error(Previous, Error) ->
fun(Data) -> _pipe = Previous(Data),
gleam@result:replace_error(_pipe, Error) end.