defmodule Mecto.SchemaExtractor do @moduledoc """ Converts an Ecto schema into a map, for use in `Mecto.SchemaValidator`. """ def convert_from(module) do case Code.ensure_compiled(module) do {:module, module} -> if function_exported?(module, :__schema__, 1) do convert_schema_to_map(module, [module]) else {:error, :missing_schema} end error -> error end end defp convert_schema_to_map(module, visited) do fields = :fields |> module.__schema__() |> Enum.map(fn field -> {field, module.__schema__(:type, field)} end) |> Enum.into(%{}) :associations |> module.__schema__() |> Enum.map(fn association -> relationship = module.__schema__(:association, association) associated_module = relationship.queryable if Enum.member?(visited, associated_module) do nil else { association, { relationship.cardinality, convert_schema_to_map(associated_module, [associated_module | visited]) } } end end) |> Enum.reject(&is_nil/1) |> Enum.into(fields) end end