defmodule OpenApiSpex.Schemax.Parser do @moduledoc """ This module is Parser for `OpenApiSpex.Schemax.schema/2` macro. In case of `:property`, this module converts camelCase fields of `OpenApiSpex.Schema` struct to snake_case fields. We will change this module to support more advanced parsing. """ def parse_body({:__block__, _, lines}), do: parse_lines(lines) def parse_body(nil), do: parse_lines([]) def parse_body(line), do: parse_lines([line]) def parse_lines(lines) do Enum.map(lines, &parse_line(&1)) end defp parse_line({:property, meta, [name, type]}) when is_atom(type), do: parse_line({:property, meta, [name, type, []]}) defp parse_line({:property, _, [name, :array, opts]}) do items = opts[:items] || raise ArgumentError, "`:array` type must come with `:items` option" opts = Keyword.delete(opts, :items) {:property, {name, [type: :array] ++ opts, items}} end defp parse_line({:property, _, [name, type, opts]}) do {:property, {name, [type: type] ++ opts}} end defp parse_line({:property, _, [name, other]}) do {:property, {name, other}} end defp parse_line({:description, _, [description]}) do {:description, description} end defp parse_line({:schema_type, _, [type]}) do {:type, type} end defp parse_line({:read_only, _, [value]}) do {:readOnly, value} end defp parse_line({:additional_properties, _, [v]}) do {:additionalProperties, v} end defp parse_line({:all_of, _, [v]}) do {:allOf, v} end defp parse_line({:one_of, _, [v]}) do {:oneOf, v} end defp parse_line({:any_of, _, [v]}) do {:anyOf, v} end defp parse_line({:multiple_of, _, [v]}) do {:multipleOf, v} end defp parse_line({:max_items, _, [v]}) do {:maxItems, v} end defp parse_line({:min_items, _, [v]}) do {:minItems, v} end defp parse_line({:max_properties, _, [v]}) do {:maxProperties, v} end defp parse_line({:min_properties, _, [v]}) do {:minProperties, v} end defp parse_line({:exclusive_minimum, _, [v]}) do {:exclusiveMinimum, v} end defp parse_line({:exclusive_maximum, _, [v]}) do {:exclusiveMaximum, v} end defp parse_line({:max_length, _, [v]}) do {:maxLength, v} end defp parse_line({:min_length, _, [v]}) do {:minLength, v} end defp parse_line({:unique_items, _, [v]}) do {:uniqueItems, v} end defp parse_line({:external_docs, _, [v]}) do {:externalDocs, v} end defp parse_line({:validate, _, [v]}) do {:"x-validate", v} end defp parse_line({key, _, [value]}) do {key, value} end defp parse_line(other) do raise ArgumentError, "unknown field. #{inspect(other)}" end end