Packages
open_api_spex
3.19.0
3.22.3
3.22.2
3.22.1
3.22.0
3.21.5
3.21.4
3.21.3
3.21.2
3.21.1
3.21.0
3.20.1
3.20.0
3.19.1
3.19.0
3.18.3
3.18.2
3.18.1
3.18.0
3.17.3
3.17.2
3.17.1
3.17.0
3.16.4
3.16.3
3.16.2
3.16.1
3.16.0
3.15.0
3.14.0
3.13.0
3.12.0
3.11.0
3.10.0
3.9.0
3.8.0
3.7.0
3.6.0
3.5.2
3.5.1
3.5.0
3.4.0
3.3.0
3.2.1
3.2.0
3.1.0
3.0.0
2.3.1
2.3.0
2.2.0
2.1.1
2.1.0
2.0.0
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
Leverage Open Api Specification 3 (swagger) to document, test, validate and explore your Plug and Phoenix APIs.
Current section
Files
Jump to
Current section
Files
lib/open_api_spex/cast/one_of.ex
defmodule OpenApiSpex.Cast.OneOf do
@moduledoc false
alias OpenApiSpex.Cast
alias OpenApiSpex.Cast.Utils
alias OpenApiSpex.Schema
def cast(%_{schema: %{type: _, oneOf: []}} = ctx) do
error(ctx, [], [])
end
def cast(%{schema: %{type: _, oneOf: schemas}} = ctx) do
castable_schemas =
Enum.reduce(schemas, {ctx, [], []}, fn schema, {ctx, results, error_schemas} ->
schema = OpenApiSpex.resolve_schema(schema, ctx.schemas)
relaxed_schema = %{schema | "x-struct": nil}
with {:ok, value} <- Cast.cast(%{ctx | errors: [], schema: relaxed_schema}),
:ok <- Utils.check_required_fields(ctx, value) do
{ctx, [{:ok, value, schema} | results], error_schemas}
else
{:error, errors} ->
{%Cast{ctx | errors: ctx.errors ++ errors}, results, [schema | error_schemas]}
end
end)
case castable_schemas do
{_, [{:ok, %_{} = value, _}], _} -> {:ok, value}
{_, [{:ok, value, %Schema{"x-struct": nil}}], _} -> {:ok, value}
{_, [{:ok, value, %Schema{"x-struct": module}}], _} -> {:ok, struct(module, value)}
{ctx, success_results, failed_schemas} -> error(ctx, success_results, failed_schemas)
end
end
## Private functions
defp error(ctx, success_results, failed_schemas) do
valid_schemas = Enum.map(success_results, &elem(&1, 2))
message =
case {valid_schemas, failed_schemas} do
{[], []} -> "no schemas given"
{[], _} -> "no schemas validate"
{_, _} -> "more than one schemas validate"
end
Cast.error(
ctx,
{:one_of,
%{
message: message,
failed_schemas: Enum.map(failed_schemas, &error_message_item/1),
valid_schemas: Enum.map(valid_schemas, &error_message_item/1)
}}
)
end
defp error_message_item({:ok, _value, schema}) do
error_message_item(schema)
end
defp error_message_item(schema) do
case schema do
%{title: title, type: type} when not is_nil(title) ->
"Schema(title: #{inspect(title)}, type: #{inspect(type)})"
%{type: type} ->
"Schema(type: #{inspect(type)})"
end
end
end