Skip to content

Commit

Permalink
feat: include map and list rules
Browse files Browse the repository at this point in the history
  • Loading branch information
heywhy committed Feb 2, 2025
1 parent ce56536 commit e8af91c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 6 deletions.
64 changes: 59 additions & 5 deletions lib/validator/rules.ex
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ defmodule Request.Validator.Rules do
{:error, "The url field must be a valid URL."}
"""
def url do
validator_fn = fn attr, value ->
fn attr, value ->
message = gettext("The %{attribute} field must be a valid URL.", attribute: attr)

value
Expand All @@ -930,8 +930,6 @@ defmodule Request.Validator.Rules do
)
|> check(message)
end

&validator_fn.(&1, &2)
end

@doc """
Expand All @@ -949,7 +947,7 @@ defmodule Request.Validator.Rules do
def active_url do
url_fn = url()

validator_fn = fn attr, value ->
fn attr, value ->
message = gettext("The %{attribute} field must be a valid URL.", attribute: attr)

case url_fn.(attr, value) do
Expand All @@ -965,8 +963,64 @@ defmodule Request.Validator.Rules do
error
end
end
end

&validator_fn.(&1, &2)
@doc """
## Examples
iex> import Request.Validator.Rules, only: [list: 0]
iex> fun = list()
iex> fun.("emails", 4)
{:error, "The emails field must be a list."}
iex> fun.("emails", ["a@b.com"])
:ok
"""
def list do
fn attr, value ->
message = gettext("The %{attribute} field must be a list.", attribute: attr)

check(is_list(value), message)
end
end

@doc """
## Examples
iex> import Request.Validator.Rules, only: [map: 0, map: 1]
iex> fun = map()
iex> metadata = %{"a" => "b", "c" => "d"}
iex> fun.("metadata", 4)
{:error, "The metadata field must be a map."}
iex> fun.("metadata", metadata)
:ok
iex> fun = map(["a", "c"])
iex> fun.("metadata", metadata)
:ok
iex> fun.("metadata", Map.put(metadata, "e", "f"))
{:error, "The metadata field must be a map."}
"""
def map(keys \\ []) when is_list(keys) do
validator_fn = fn keys, attr, value ->
message = gettext("The %{attribute} field must be a map.", attribute: attr)

cond =
case keys do
[] -> is_map(value)
keys -> is_map(value) and diff_keys_empty?(value, keys)
end

check(cond, message)
end

&validator_fn.(keys, &1, &2)
end

defp diff_keys_empty?(map, keys) when is_map(map) and is_list(keys) do
map
|> Map.keys()
|> MapSet.new()
|> MapSet.symmetric_difference(MapSet.new(keys))

Check warning on line 1022 in lib/validator/rules.ex

View workflow job for this annotation

GitHub Actions / test

MapSet.symmetric_difference/2 is undefined or private

Check warning on line 1022 in lib/validator/rules.ex

View workflow job for this annotation

GitHub Actions / analyze

MapSet.symmetric_difference/2 is undefined or private
|> Enum.empty?()
end

defp check_with_op(first, second, op, messages) do
Expand Down
12 changes: 11 additions & 1 deletion priv/gettext/default.pot
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,17 @@ msgid "The %{attribute} field must contain %{size} items."
msgstr ""

#: lib/validator/rules.ex:921
#: lib/validator/rules.ex:953
#: lib/validator/rules.ex:951
#, elixir-autogen, elixir-format
msgid "The %{attribute} field must be a valid URL."
msgstr ""

#: lib/validator/rules.ex:980
#, elixir-autogen, elixir-format
msgid "The %{attribute} field must be a list."
msgstr ""

#: lib/validator/rules.ex:1004
#, elixir-autogen, elixir-format
msgid "The %{attribute} field must be a map."
msgstr ""

0 comments on commit e8af91c

Please sign in to comment.