Skip to content

Instantly share code, notes, and snippets.

@tyre
Created June 13, 2015 18:25
Show Gist options
  • Save tyre/ef7fb41fbb407663e2d6 to your computer and use it in GitHub Desktop.
Save tyre/ef7fb41fbb407663e2d6 to your computer and use it in GitHub Desktop.
defmodule RequiredFields do
defmacro __using__(_opts) do
quote do
def new(attributes) do
Map.merge(%__MODULE__{}, attributes)
|> validate
end
def validate(struct) do
missing = missing_attributes(struct)
if Enum.any? missing do
raise "#{__MODULE__} requires #{Enum.join(missing, ", ")} field(s)"
else
struct
end
end
defp missing_attributes(struct) do
Enum.reduce(@required_attributes, [], fn (attr, missing) ->
if Map.get(struct, attr) do
missing
else
[attr | missing]
end
end)
end
end
end
end
defmodule Walrus do
defstruct name: nil, favorite_color: nil
@required_attributes [:name]
use RequiredFields
end
IO.puts inspect Walrus.new(%{name: "Frank"})
IO.puts inspect Walrus.new(%{name: "Frank", favorite_color: "purple"})
IO.puts inspect Walrus.new(%{favorite_color: "purple"})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment