Skip to content

Instantly share code, notes, and snippets.

@joeletizia
Last active August 21, 2016 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joeletizia/18044e70a936115d103db2bf6ae10c8a to your computer and use it in GitHub Desktop.
Save joeletizia/18044e70a936115d103db2bf6ae10c8a to your computer and use it in GitHub Desktop.
defmodule Success do
@type t :: %Success{value: any}
defstruct value: nil
end
defmodule Failure do
@type t :: %Failure{value: any, reason: String.t}
defstruct value: nil, reason: nil
end
defmodule Users do
defmodule UserNameValidation do
@spec validate(String.t) :: Success.t | Failure.t
def validate(user_name) do
%Success{value: user_name}
|> ensure_length
|> ensure_characters_only
|> ensure_no_dirty_words
end
@spec ensure_length(Success.t) :: Failure.t | Success.t
@spec ensure_length(Failure.t) :: Failure.t
defp ensure_length(%Failure{} = error_struct), do: error_struct
defp ensure_length(%Success{value: user_name} = struct) do
cond do
String.length(user_name) > 15 -> %Failure{value: user_name, reason: :too_long}
true -> struct
end
end
@spec ensure_characters_only(Success.t) :: Failure.t | Success.t
@spec ensure_characters_only(Failure.t) :: Failure.t
defp ensure_characters_only(%Failure{} = error_struct), do: error_struct
defp ensure_characters_only(%Success{value: user_name} = struct) do
if Regex.match?(~r/^[a-zA-Z]+$/, user_name) do
struct
else
%Failure{value: user_name, reason: :contains_illegal_characters}
end
end
@spec ensure_no_dirty_words(Success.t) :: Failure.t | Success.t
@spec ensure_no_dirty_words(Failure.t) :: Failure.t
defp ensure_no_dirty_words(%Failure{} = error_struct), do: error_struct
defp ensure_no_dirty_words(%Success{value: user_name} = struct) do
if DirtyWords.word_is_dirty?(user_name) do
%Failure{value: user_name, reason: :contains_dirty_words}
else
struct
end
end
end
end
defmodule DirtyWords do
@spec word_is_dirty?(String.t, module) :: boolean
def word_is_dirty?(word, dirty_words_repo \\ DirtyWords.Repo) do
Enum.any?(dirty_words_repo.all, fn(dirty_word) ->
Regex.match?(~r/#{dirty_word}/, word)
end)
end
defmodule Repo do
@spec all :: list(String.t)
def all do
[
"butt"
]
end
end
end
defmodule Success do
@type t :: %Success{value: any}
defstruct value: nil
end
defmodule Failure do
@type t :: %Failure{value: any, reason: String.t}
defstruct value: nil, reason: nil
end
defmodule Users do
defmodule UserNameValidation do
@spec ensure_length(Success.t) :: Failure.t | Success.t
@spec ensure_length(Failure.t) :: Failure.t
defp ensure_length(%Failure{} = error_struct), do: error_struct
defp ensure_length(%Success{value: user_name} = struct) do
cond do
String.length(user_name) > 15 -> %Failure{value: user_name, reason: :too_long}
true -> struct
end
%Failure{}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment