defmodule Shake.Validate do @moduledoc false defmacro __using__(_opts) do quote do import Shake.Frame def validate(frame, opts) do case Keyword.split(opts, [:with]) do {[] , _opts} -> halt(frame, "Validate requires a 'with: &func/2' option") {[with: func], opts2} -> validate(frame, func, opts2) end end def validate(frame, func, opts) when is_atom(func) do validate(frame, [func], opts) end def validate(frame, funclist, opts) when is_list(funclist) do Enum.reduce funclist, frame, fn(func, acc) -> halt_msg = acc.halt_msg newfunc = cond do is_atom(func) -> fn(acc, opts) -> apply(__MODULE__, func, [acc, opts]) end true -> func end newframe = newfunc.(acc, opts) if newframe.halt_msg != halt_msg do case halt_msg do "" -> %Shake.Frame{newframe | halt_msg: [newframe.halt_msg]} _ -> %Shake.Frame{newframe | halt_msg: halt_msg ++ [newframe.halt_msg]} end else newframe end end end end end end