Packages
open_api_spex
2.3.1
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/discriminator.ex
defmodule OpenApiSpex.Discriminator do
@moduledoc """
Defines the `OpenApiSpex.Discriminator.t` type.
"""
alias OpenApiSpex.Schema
@enforce_keys :propertyName
defstruct [
:propertyName,
:mapping
]
@typedoc """
[Discriminator Object](https://swagger.io/specification/#discriminatorObject)
When request bodies or response payloads may be one of a number of different schemas,
a discriminator object can be used to aid in serialization, deserialization, and validation.
The discriminator is a specific object in a schema which is used to inform the consumer of the
specification of an alternative schema based on the value associated with it.
"""
@type t :: %__MODULE__{
propertyName: String.t,
mapping: %{String.t => String.t} | nil
}
@doc """
Resolve the schema that should be used to cast/validate a value using a `Discriminator`.
"""
@spec resolve(t, map, %{String.t => Schema.t}) :: {:ok, Schema.t} | {:error, String.t}
def resolve(%{propertyName: name, mapping: mapping}, value = %{}, schemas = %{}) do
with {:ok, val} <- get_property_value(value, name) do
mapped = map_property_value(mapping, val)
lookup_schema(schemas, mapped)
else
{:error, reason} -> {:error, reason}
end
end
@spec get_property_value(map, String.t) :: {:ok, any} | {:error, String.t}
defp get_property_value(value = %{}, property_name) do
case Map.fetch(value, property_name) do
{:ok, val} -> {:ok, val}
:error -> {:error, "No value for required disciminator property: #{property_name}"}
end
end
@spec map_property_value(%{String.t => String.t} | nil, String.t) :: String.t
defp map_property_value(nil, val), do: val
defp map_property_value(mapping = %{}, val) do
Map.get(mapping, val, val)
end
@spec lookup_schema(%{String.t => Schema.t}, String.t) :: {:ok, Schema.t} | {:error, String.t}
defp lookup_schema(schemas, "#components/schemas/" <> name) do
lookup_schema(schemas, name)
end
defp lookup_schema(schemas, name) do
case Map.fetch(schemas, name) do
{:ok, schema} -> {:ok, schema}
:error -> {:error, "Unknown schema: #{name}"}
end
end
end