Skip to content

Commit

Permalink
Cast discriminator when no title present
Browse files Browse the repository at this point in the history
  • Loading branch information
Alberto Sartori committed Nov 17, 2023
1 parent 7c05fa0 commit 702c703
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 16 deletions.
34 changes: 19 additions & 15 deletions lib/open_api_spex/cast/discriminator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ defmodule OpenApiSpex.Cast.Discriminator do
end
end

defp cast_discriminator(%_{value: %{} = value, schema: schema} = ctx) do
defp cast_discriminator(%_{value: %{} = value, schema: schema, schemas: schemas} = ctx) do
{discriminator_property, mappings} = discriminator_details(schema)

case value["#{discriminator_property}"] || value[discriminator_property] do
Expand All @@ -49,7 +49,7 @@ defmodule OpenApiSpex.Cast.Discriminator do
# or return an error according to the Open API Spec.
composite_ctx = %{ctx | schema: %{schema | discriminator: nil}}

cast_composition(composite_ctx, ctx, discriminator_value, mappings)
cast_composition(composite_ctx, ctx, discriminator_value, mappings, schemas)
end
end

Expand All @@ -62,7 +62,8 @@ defmodule OpenApiSpex.Cast.Discriminator do
%_{schema: %{allOf: [_ | _]}} = composite_ctx,
ctx,
discriminator_value,
mappings
mappings,
schemas
) do
with {composite_schemas, cast_composition_result} <-
{locate_composition_schemas(composite_ctx), Cast.cast(composite_ctx)},
Expand All @@ -71,7 +72,8 @@ defmodule OpenApiSpex.Cast.Discriminator do
find_discriminator_schema(
discriminator_value,
mappings,
composite_schemas
composite_schemas,
schemas
) do
Cast.cast(%{composite_ctx | schema: schema})
else
Expand All @@ -80,37 +82,39 @@ defmodule OpenApiSpex.Cast.Discriminator do
end
end

defp cast_composition(composite_ctx, ctx, discriminator_value, mappings) do
defp cast_composition(composite_ctx, ctx, discriminator_value, mappings, schemas) do
with composite_schemas <- locate_composition_schemas(composite_ctx),
%{} = schema <- find_discriminator_schema(discriminator_value, mappings, composite_schemas) do
%{} = schema <-
find_discriminator_schema(discriminator_value, mappings, composite_schemas, schemas) do
Cast.cast(%{composite_ctx | schema: schema})
else
nil -> error(:invalid_discriminator_value, ctx)
{:error, _} = error -> error
end
end

defp find_discriminator_schema(discriminator, mappings = %{}, schemas) do
defp find_discriminator_schema(discriminator, mappings = %{}, composite_schemas, schemas) do
case Map.fetch(mappings, discriminator) do
{:ok, "#/components/schemas/" <> name} ->
find_discriminator_schema(name, nil, schemas)
find_discriminator_schema(name, nil, composite_schemas, schemas) || Map.get(schemas, name)

{:ok, name} ->
find_discriminator_schema(name, nil, schemas)
find_discriminator_schema(name, nil, composite_schemas, schemas)

:error ->
find_discriminator_schema(discriminator, nil, schemas)
find_discriminator_schema(discriminator, nil, composite_schemas, schemas)
end
end

defp find_discriminator_schema(discriminator, _mappings, schemas)
defp find_discriminator_schema(discriminator, nil, composite_schemas, _schemas)
when is_atom(discriminator) and not is_nil(discriminator),
do: Enum.find(schemas, &Kernel.==(&1."x-struct", discriminator))
do: Enum.find(composite_schemas, &Kernel.==(&1."x-struct", discriminator))

defp find_discriminator_schema(discriminator, _mappings, schemas) when is_binary(discriminator),
do: Enum.find(schemas, &Kernel.==(&1.title, discriminator))
defp find_discriminator_schema(discriminator, nil, composite_schemas, _schemas)
when is_binary(discriminator),
do: Enum.find(composite_schemas, &Kernel.==(&1.title, discriminator))

defp find_discriminator_schema(_discriminator, _mappings, _schemas), do: nil
defp find_discriminator_schema(_discriminator, _mappings, _composite_schemas, _schemas), do: nil

defp discriminator_details(%{discriminator: %{propertyName: property_name, mapping: mappings}}),
do: {String.to_existing_atom(property_name), mappings}
Expand Down
2 changes: 1 addition & 1 deletion test/mix/tasks/openapi.spec.json_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ defmodule Mix.Tasks.Openapi.Spec.JsonTest do
Mix.Tasks.Openapi.Spec.Json.run(~w(
--quiet=true
--spec OpenApiSpexTest.Tasks.SpecModule
"tmp/openapi.json"
tmp/openapi.json
))

refute_received {:mix_shell, :info, ["* creating tmp"]}
Expand Down

0 comments on commit 702c703

Please sign in to comment.