-module(valguard). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/valguard.gleam"). -export([append_error/2, list/2, collect_errors/1, prepare/1, prepare_with/2, with/3, with_optional/3, int_required/2, int_min/3, int_max/3, float_required/2, float_min/3, float_max/3, string_required/2, string_min/3, string_max/3, date_is_valid/2, email_is_valid/2]). -export_type([validation_error/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. -type validation_error() :: {validation_error, binary(), binary()}. -file("src/valguard.gleam", 18). ?DOC( " Takes a validation result and list of validation errors\n" " If result is error, it adds it to the list\n" ). -spec append_error( {ok, nil} | {error, validation_error()}, list(validation_error()) ) -> list(validation_error()). append_error(Result, List) -> case Result of {error, Validation_error} -> lists:append(List, [Validation_error]); {ok, nil} -> List end. -file("src/valguard.gleam", 86). ?DOC(" Inner recursive loop for list\n"). -spec list_inner( list(fun(() -> {ok, nil} | {error, binary()})), {ok, nil} | {error, binary()} ) -> {ok, nil} | {error, binary()}. list_inner(List, Prev) -> gleam@result:'try'(Prev, fun(_) -> case List of [] -> Prev; [Next | Rest] -> list_inner(Rest, Next()) end end). -file("src/valguard.gleam", 74). ?DOC( " Validates a list of requirements lazily.\n" "\n" " Takes a key and list of validation functions.\n" "\n" " Returns Ok(Nil) if success or Error(String) at first issue\n" ). -spec list(binary(), list(fun(() -> {ok, nil} | {error, binary()}))) -> {ok, nil} | {error, validation_error()}. list(Key, List) -> case list_inner(List, {ok, nil}) of {ok, nil} -> {ok, nil}; {error, Value} -> {error, {validation_error, Key, Value}} end. -file("src/valguard.gleam", 32). ?DOC( " Takes a list of validation results and returns a list of the errors\n" " Returns an empty list if no errors\n" ). -spec collect_errors(list({ok, nil} | {error, validation_error()})) -> list(validation_error()). collect_errors(Inputs) -> gleam@list:filter_map(Inputs, fun(X) -> case X of {ok, nil} -> {error, nil}; {error, Validation_error} -> {ok, Validation_error} end end). -file("src/valguard.gleam", 46). ?DOC( " Takes a list of validation errors and converts it to a result\n" " Returns ok if list is empty\n" ). -spec prepare(list(validation_error())) -> {ok, nil} | {error, list(validation_error())}. prepare(Errors) -> case gleam@list:is_empty(Errors) of true -> {ok, nil}; false -> {error, Errors} end. -file("src/valguard.gleam", 59). ?DOC( " Takes a list of validation errors and converts it to a result\n" " wrapping the errors in a custom type. Returns Ok(Nil) if list is empty.\n" "\n" " This functions similar to `valguard.prepare`.\n" ). -spec prepare_with( list(validation_error()), fun((list(validation_error())) -> EIJ) ) -> {ok, nil} | {error, EIJ}. prepare_with(Errors, Custom_type) -> case gleam@list:is_empty(Errors) of true -> {ok, nil}; false -> {error, Custom_type(Errors)} end. -file("src/valguard.gleam", 139). ?DOC(" Inner recursive loop for with\n"). -spec with_inner( list(fun((EJM) -> {ok, nil} | {error, binary()})), EJM, {ok, nil} | {error, binary()} ) -> {ok, nil} | {error, binary()}. with_inner(List, Value, Prev) -> gleam@result:'try'(Prev, fun(_) -> case List of [] -> Prev; [Next | Rest] -> with_inner(Rest, Value, Next(Value)) end end). -file("src/valguard.gleam", 104). ?DOC( " Validates a list of requirements lazily.\n" "\n" " Takes a key, value and list of validation functions.\n" "\n" " Runs validation functions lazily and returns the result.\n" " Returns Ok(Nil) if success or Error(String) at first issue\n" ). -spec with(binary(), EIZ, list(fun((EIZ) -> {ok, nil} | {error, binary()}))) -> {ok, nil} | {error, validation_error()}. with(Key, Value, List) -> case with_inner(List, Value, {ok, nil}) of {ok, nil} -> {ok, nil}; {error, Value@1} -> {error, {validation_error, Key, Value@1}} end. -file("src/valguard.gleam", 123). ?DOC( " Validates a list of requirements lazily.\n" "\n" " Takes a key, an optional value and list of validation functions.\n" "\n" " Runs validation functions lazily and returns the result.\n" " Returns Ok(Nil) if optional value is None or all validations are successful.\n" " Returns Error(String) at first issue.\n" ). -spec with_optional( binary(), gleam@option:option(EJF), list(fun((EJF) -> {ok, nil} | {error, binary()})) ) -> {ok, nil} | {error, validation_error()}. with_optional(Key, Option, List) -> valguard@internal@utils:some_or( Option, {ok, nil}, fun(Value) -> case with_inner(List, Value, {ok, nil}) of {ok, nil} -> {ok, nil}; {error, Value@1} -> {error, {validation_error, Key, Value@1}} end end ). -file("src/valguard.gleam", 160). ?DOC(" Requires a int to be less than or greater than 0 to be considered required\n"). -spec int_required(integer(), binary()) -> {ok, nil} | {error, binary()}. int_required(Value, Message) -> case Value /= 0 of true -> {ok, nil}; false -> {error, Message} end. -file("src/valguard.gleam", 168). ?DOC(" Validates an int is at least a minimum value. Returns an error if value is less than the minimum\n"). -spec int_min(integer(), integer(), binary()) -> {ok, nil} | {error, binary()}. int_min(Value, Minimum, Message) -> case Value < Minimum of true -> {error, Message}; false -> {ok, nil} end. -file("src/valguard.gleam", 180). ?DOC(" Validates an int is at most a maximum value. Returns an error if value is greater than the maximum\n"). -spec int_max(integer(), integer(), binary()) -> {ok, nil} | {error, binary()}. int_max(Value, Maximum, Message) -> case Value > Maximum of true -> {error, Message}; false -> {ok, nil} end. -file("src/valguard.gleam", 192). ?DOC(" Requires a float to be less than or greater than 0.0 to be considered required\n"). -spec float_required(float(), binary()) -> {ok, nil} | {error, binary()}. float_required(Value, Message) -> case (Value > +0.0) orelse (Value < +0.0) of true -> {ok, nil}; false -> {error, Message} end. -file("src/valguard.gleam", 203). ?DOC(" Validates a float is at least a minimum value. Returns an error if value is less than the minimum\n"). -spec float_min(float(), float(), binary()) -> {ok, nil} | {error, binary()}. float_min(Value, Minimum, Message) -> case Value < Minimum of true -> {error, Message}; false -> {ok, nil} end. -file("src/valguard.gleam", 215). ?DOC(" Validates a float is at most a maximum value. Returns an error if value is greater than the maximum\n"). -spec float_max(float(), float(), binary()) -> {ok, nil} | {error, binary()}. float_max(Value, Maximum, Message) -> case Value > Maximum of true -> {error, Message}; false -> {ok, nil} end. -file("src/valguard.gleam", 227). ?DOC(" Requires a string to not be empty to be considered required\n"). -spec string_required(binary(), binary()) -> {ok, nil} | {error, binary()}. string_required(Value, Message) -> case gleam@string:is_empty(Value) of false -> {ok, nil}; true -> {error, Message} end. -file("src/valguard.gleam", 238). ?DOC(" Validates a string is a minimum length\n"). -spec string_min(binary(), integer(), binary()) -> {ok, nil} | {error, binary()}. string_min(Value, Minimum, Message) -> case string:length(Value) < Minimum of true -> {error, Message}; false -> {ok, nil} end. -file("src/valguard.gleam", 250). ?DOC(" Validates a string is at most a maximum length\n"). -spec string_max(binary(), integer(), binary()) -> {ok, nil} | {error, binary()}. string_max(Value, Maximum, Message) -> case string:length(Value) > Maximum of true -> {error, Message}; false -> {ok, nil} end. -file("src/valguard.gleam", 285). ?DOC(" Validates that a date is valid by checking it can be parsed correctly\n"). -spec date_is_valid(binary(), binary()) -> {ok, nil} | {error, binary()}. date_is_valid(Datetime, Message) -> case gleam@time@timestamp:parse_rfc3339(Datetime) of {ok, _} -> {ok, nil}; {error, _} -> {error, Message} end. -file("src/valguard.gleam", 269). ?DOC(" Validates if entered email is a valid email address\n"). -spec email_is_valid(binary(), binary()) -> {ok, nil} | {error, binary()}. email_is_valid(Email, Message) -> gleam@result:'try'( begin _pipe = gleam@regexp:from_string( <<"^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"/utf8>> ), gleam@result:replace_error(_pipe, Message) end, fun(Re) -> case gleam@regexp:check(Re, Email) of false -> {error, Message}; true -> {ok, nil} end end ).