Skip to content

Commit

Permalink
Add email validation to Mayo.String and add enum support to length va…
Browse files Browse the repository at this point in the history
…lidation
  • Loading branch information
tommy351 committed Jul 3, 2016
1 parent fc9b924 commit 59df8af
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 58 deletions.
58 changes: 20 additions & 38 deletions lib/mayo/access.ex
Original file line number Diff line number Diff line change
@@ -1,41 +1,23 @@
defmodule Mayo.Access do
def fetch(value, key) when is_map(value) do
Map.fetch(value, key)
end

def fetch(value, key) when is_list(value) do
Keyword.fetch(value, key)
end

def get(value, key) when is_map(value) do
Map.get(value, key)
end

def get(value, key) when is_list(value) do
Keyword.get(value, key)
end

def put(value, key, new) when is_map(value) do
Map.put(value, key, new)
end

def put(value, key, new) when is_list(value) do
Keyword.put(value, key, new)
end

def delete(value, key) when is_map(value) do
Map.delete(value, key)
end

def delete(value, key) when is_list(value) do
Keyword.delete(value, key)
end
defprotocol Mayo.Access do
def fetch(value, key)
def get(value, key)
def put(value, key, new)
def delete(value, key)
def keys(value)
end

def keys(value) when is_map(value) do
Map.keys(value)
end
defimpl Mayo.Access, for: Map do
defdelegate fetch(value, key), to: Map
defdelegate get(value, key), to: Map
defdelegate put(value, key, new), to: Map
defdelegate delete(value, key), to: Map
defdelegate keys(value), to: Map
end

def keys(value) when is_list(value) do
Keyword.keys(value)
end
defimpl Mayo.Access, for: List do
defdelegate fetch(value, key), to: Keyword
defdelegate get(value, key), to: Keyword
defdelegate put(value, key, new), to: Keyword
defdelegate delete(value, key), to: Keyword
defdelegate keys(value), to: Keyword
end
24 changes: 16 additions & 8 deletions lib/mayo/list.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule Mayo.List do
iex> Mayo.List.min([], 3)
{:error, %Mayo.Error{type: "list.min"}}
"""
def min(value, len) when is_list(value) and length(value) == len, do: value
def min(value, limit) when is_list(value) and length(value) == limit, do: value

def min(value, _) when is_list(value) do
{:error, %Mayo.Error{
Expand All @@ -27,7 +27,7 @@ defmodule Mayo.List do
iex> Mayo.List.max([1, 2, 3, 4], 3)
{:error, %Mayo.Error{type: "list.max"}}
"""
def max(value, len) when is_list(value) and length(value) == len, do: value
def max(value, limit) when is_list(value) and length(value) == limit, do: value

def max(value, _) when is_list(value) do
{:error, %Mayo.Error{
Expand All @@ -43,16 +43,24 @@ defmodule Mayo.List do
iex> Mayo.List.length([1, 2, 3], 3)
[1, 2, 3]
iex> Mayo.List.length([1, 2, 3], 2..6)
[1, 2, 3]
iex> Mayo.List.length([1], 3)
{:error, %Mayo.Error{type: "list.length"}}
"""
def length(value, len) when is_list(value) and length(value) == len, do: value

def length(value, _) when is_list(value) do
{:error, %Mayo.Error{
type: "list.length"
}}
def length(value, limit) when is_list(value) do
if test_length(value, limit) do
value
else
{:error, %Mayo.Error{
type: "list.length"
}}
end
end

def length(value, _), do: value

defp test_length(value, limit) when is_number(limit), do: length(value) == limit
defp test_length(value, limit), do: Enum.member?(limit, length(value))
end
18 changes: 12 additions & 6 deletions lib/mayo/map.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ defmodule Mayo.Map do
iex> Mayo.Map.min(%{}, 1)
{:error, %Mayo.Error{type: "map.min"}}
"""
def min(value, len) when is_map(value) do
if length(Map.keys(value)) < len do
def min(value, limit) when is_map(value) do
if length(Map.keys(value)) < limit do
{:error, %Mayo.Error{
type: "map.min"
}}
Expand All @@ -29,8 +29,8 @@ defmodule Mayo.Map do
iex> Mayo.Map.max(%{foo: "bar", baz: "boo"}, 1)
{:error, %Mayo.Error{type: "map.max"}}
"""
def max(value, len) when is_map(value) do
if length(Map.keys(value)) > len do
def max(value, limit) when is_map(value) do
if length(Map.keys(value)) > limit do
{:error, %Mayo.Error{
type: "map.max"
}}
Expand All @@ -47,11 +47,14 @@ defmodule Mayo.Map do
iex> Mayo.Map.length(%{foo: "bar"}, 1)
%{foo: "bar"}
iex> Mayo.Map.length(%{foo: "bar"}, 1..3)
%{foo: "bar"}
iex> Mayo.Map.length(%{}, 1)
{:error, %Mayo.Error{type: "map.length"}}
"""
def length(value, len) when is_map(value) do
if length(Map.keys(value)) == len do
def length(value, limit) when is_map(value) do
if test_length(value, limit) do
value
else
{:error, %Mayo.Error{
Expand All @@ -62,6 +65,9 @@ defmodule Mayo.Map do

def length(value, _), do: value

defp test_length(value, limit) when is_number(limit), do: length(Map.keys(value)) == limit
defp test_length(value, limit), do: Enum.member?(limit, length(Map.keys(value)))

@doc """
Checks the presence of keys.
Expand Down
42 changes: 36 additions & 6 deletions lib/mayo/string.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ defmodule Mayo.String do
# https://github.com/hapijs/joi/blob/v8.4.2/lib/string.js#L170
@token_pattern ~r/^\w+$/

# http://emailregex.com/
@email_pattern ~r/(?:[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/

@doc """
Checks the minimum length of a string.
Expand All @@ -20,8 +23,8 @@ defmodule Mayo.String do
iex> Mayo.String.min("t", 3)
{:error, %Mayo.Error{type: "string.min"}}
"""
def min(value, len) when is_binary(value) do
if String.length(value) < len do
def min(value, limit) when is_binary(value) do
if String.length(value) < limit do
{:error, %Mayo.Error{
type: "string.min"
}}
Expand All @@ -41,8 +44,8 @@ defmodule Mayo.String do
iex> Mayo.String.max("bucket", 5)
{:error, %Mayo.Error{type: "string.max"}}
"""
def max(value, len) when is_binary(value) do
if String.length(value) > len do
def max(value, limit) when is_binary(value) do
if String.length(value) > limit do
{:error, %Mayo.Error{
type: "string.max"
}}
Expand All @@ -59,11 +62,14 @@ defmodule Mayo.String do
iex> Mayo.String.length("test", 4)
"test"
iex> Mayo.String.length("test", 2..6)
"test"
iex> Mayo.String.length("test", 5)
{:error, %Mayo.Error{type: "string.length"}}
"""
def length(value, len) when is_binary(value) do
if String.length(value) == len do
def length(value, limit) when is_binary(value) do
if test_length(value, limit) do
value
else
{:error, %Mayo.Error{
Expand All @@ -74,6 +80,9 @@ defmodule Mayo.String do

def length(value, _), do: value

defp test_length(value, limit) when is_number(limit), do: String.length(value) == limit
defp test_length(value, limit), do: Enum.member?(limit, String.length(value))

@doc """
Checks if the string is a valid UUID.
Expand Down Expand Up @@ -222,4 +231,25 @@ defmodule Mayo.String do
end

def token(value), do: value

@doc """
Checks if the string is a valid email.
iex> Mayo.String.email("tommy@gmail.com")
"tommy@gmail.com"
iex> Mayo.String.email("test")
{:error, %Mayo.Error{type: "string.email"}}
"""
def email(value) when is_binary(value) do
if String.match?(value, @email_pattern) do
value
else
{:error, %Mayo.Error{
type: "string.email"
}}
end
end

def email(value), do: value
end

0 comments on commit 59df8af

Please sign in to comment.