-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.