defmodule Exonerate.Metadata do @moduledoc false alias Exonerate.Tools # defp functions can't create metadata. defmacro functions(:defp, _, _, _), do: nil defmacro functions(type, function_name, resource, pointer, opts) do __CALLER__ |> Tools.subschema(resource, pointer) |> build_functions(type, function_name, metadatas(opts)) end def schema(_, :defp, _), do: nil def schema(schema_str, type, function_name, opts) do metadata_opts = List.wrap(opts[:metadata]) schema_value = Tools.decode!(schema_str, opts) if metadata_opts == [true] or :schema in metadata_opts do quote do unquote(type)(unquote(function_name)(:schema), do: unquote(Macro.escape(schema_value))) end end end # note that the schema metadata isn't here because this function would pull the # degeneracy-optimized schema from the cache, which is not what we want. Instead, # we generate schema metadata at the callsite using the above ast function. @all_metadata [:id, :schema_id, :title, :description, :examples, :default] defp metadatas(opts) do case opts[:metadata] do true -> @all_metadata nil_or_list -> List.wrap(nil_or_list) end end defp build_functions(schema, _, _, _) when is_boolean(schema), do: nil defp build_functions(schema, type, function_name, metadatas) do quote do unquote(id(schema, type, function_name, metadatas)) unquote(schema_id(schema, type, function_name, metadatas)) unquote(title(schema, type, function_name, metadatas)) unquote(description(schema, type, function_name, metadatas)) unquote(examples(schema, type, function_name, metadatas)) unquote(default(schema, type, function_name, metadatas)) end end defp id(schema, type, function_name, metadatas) do if id = :id in metadatas and (schema["$id"] || schema["id"]) do quote do unquote(type)(unquote(function_name)(:id), do: unquote(id)) end end end defp schema_id(schema, type, function_name, metadatas) do if schema_id = :schema_id in metadatas and schema["$schema"] do quote do unquote(type)(unquote(function_name)(:schema_id), do: unquote(schema_id)) end end end defp title(schema, type, function_name, metadatas) do if title = :title in metadatas and schema["title"] do quote do unquote(type)(unquote(function_name)(:title), do: unquote(title)) end end end defp description(schema, type, function_name, metadatas) do if description = :description in metadatas and schema["description"] do quote do unquote(type)(unquote(function_name)(:description), do: unquote(description)) end end end defp examples(schema, type, function_name, metadatas) do if examples = :examples in metadatas and schema["examples"] do quote do unquote(type)(unquote(function_name)(:examples), do: unquote(Macro.escape(examples))) end end end defp default(schema, type, function_name, metadatas) do if default = :default in metadatas and schema["default"] do quote do unquote(type)(unquote(function_name)(:default), do: unquote(Macro.escape(default))) end end end end