Elixir Generic Validation Decorator. Quote and Unquote

Viewed 50

Is it possible to create a generic param validation in elixir?

Here is my current attempt using the decorator package.

Controller

defmodule MyController do
  use ArgsValidator
  

  @decorate validate(uuid: &is_bitstring/1)
  defdelegate resource(uuid, opts \\ []), 
    to: ResourceByUUID,
    as: :call
end

Decorator Definition

defmodule ArgsValidator do
  use Decorator.Define, validate: 1

  def validate(args, body, %{args: function_args = [uuid, _opts]}) do
    quote do
      if Enum.map(unquote(args), fn {param_key, validation} ->
           #           candidate = Enum.at(function_args, 0)               # undefined function func_args/0
           #           candidate = Enum.at(unquote(function_args), 0)      # undefined function \\/2
           #          candidate = List.keyfind(function_args, param_key, 0)
           #          apply(validation, [unquote(candidate)])

           apply(validation, [unquote(uuid)])
         end)
         |> Enum.any?(&(!&1)) do
        {:error, :validation_failed}
      else
        unquote(body)
      end
    end
  end
end

The issue I have is the code that is commented out.

I can execute the validation function to the candidate if I pattern match the function args and pull out the specific parameter, but I would like to get the correct parameter in a generic lookup fashion like my commented out code would do it.

I'm not sure why I can not reference function_args if it is unquoted or even quoted.

0 Answers
Related