Skip to content

Commit ab40012

Browse files
committed
Handle the case where Schema.type is an array
1 parent 02d8c15 commit ab40012

File tree

2 files changed

+47
-67
lines changed

2 files changed

+47
-67
lines changed

lib/open_api_spex/open_api/decode.ex

+46-66
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
102102
end
103103
end
104104

105-
# In some cases, e.g. Schema type we must convert values that are strings to atoms,
106-
# for example Schema.type should be one of:
107-
#
108-
# :string | :number | :integer | :boolean | :array | :object
105+
# In some cases, e.g. Schema type we must convert values that are strings to atoms.
109106
#
110107
# This function, ensures that if the map has the key — it'll convert the corresponding value
111108
# to an atom.
@@ -127,11 +124,25 @@ defmodule OpenApiSpex.OpenApi.Decode do
127124
update_map_if_key_present(map, key, &Enum.map(&1, map_fn))
128125
end
129126

127+
# In some cases, e.g. Schema type we must convert values that are either strings or list of strings to a atoms or list of atoms,
128+
#
129+
# This function, ensures that if the map has the key — it'll convert the corresponding value
130+
# to an atom or list of atoms.
131+
defp convert_value_to_atom_or_list_of_atoms_if_present(map, key) do
132+
update_fn = fn
133+
nil -> nil
134+
l when is_list(l) -> Enum.map(l, &String.to_atom/1)
135+
s -> String.to_atom(s)
136+
end
137+
138+
update_map_if_key_present(map, key, update_fn)
139+
end
140+
130141
# The Schema.type and Schema.required keys require some special treatment since their
131142
# values should be converted to atoms
132143
defp prepare_schema(map) do
133144
map
134-
|> convert_value_to_atom_if_present("type")
145+
|> convert_value_to_atom_or_list_of_atoms_if_present("type")
135146
|> convert_value_to_atom_if_present("format")
136147
|> convert_value_to_atom_if_present("x-struct")
137148
|> convert_value_to_list_of_atoms_if_present("required")
@@ -206,69 +217,38 @@ defmodule OpenApiSpex.OpenApi.Decode do
206217

207218
defp to_struct(%{"$ref" => _} = map, Schema), do: struct_from_map(Reference, map)
208219

209-
defp to_struct(%{"type" => type} = map, Schema)
210-
when type in ~w(number integer boolean string) do
211-
map
212-
|> prepare_schema()
213-
|> (&struct_from_map(Schema, &1)).()
214-
|> prop_to_struct(:xml, Xml)
215-
|> add_extensions(map)
216-
end
217-
218-
defp to_struct(%{"type" => "array"} = map, Schema) do
219-
map
220-
|> prepare_schema()
221-
|> (&struct_from_map(Schema, &1)).()
222-
|> prop_to_struct(:items, Schema)
223-
|> prop_to_struct(:xml, Xml)
224-
|> add_extensions(map)
225-
end
226-
227-
defp to_struct(%{"anyOf" => _valid_schemas} = map, Schema) do
228-
Schema
229-
|> struct_from_map(prepare_schema(map))
230-
|> prop_to_struct(:anyOf, Schemas)
231-
|> prop_to_struct(:discriminator, Discriminator)
232-
|> add_extensions(map)
233-
end
234-
235-
defp to_struct(%{"oneOf" => _valid_schemas} = map, Schema) do
236-
Schema
237-
|> struct_from_map(prepare_schema(map))
238-
|> prop_to_struct(:oneOf, Schemas)
239-
|> prop_to_struct(:discriminator, Discriminator)
240-
|> add_extensions(map)
241-
end
242-
243-
defp to_struct(%{"allOf" => _valid_schemas} = map, Schema) do
244-
Schema
245-
|> struct_from_map(prepare_schema(map))
246-
|> prop_to_struct(:allOf, Schemas)
247-
|> prop_to_struct(:discriminator, Discriminator)
248-
|> add_extensions(map)
249-
end
250-
251-
defp to_struct(%{"type" => "object"} = map, Schema) do
252-
map
253-
|> Map.update("properties", %{}, fn v ->
254-
v
255-
|> Map.new(fn {k, v} ->
256-
{String.to_atom(k), v}
220+
defp to_struct(map, Schema) do
221+
a =
222+
map
223+
|> update_map_if_key_present("properties", fn v ->
224+
v
225+
|> Map.new(fn {k, v} ->
226+
{String.to_atom(k), v}
227+
end)
257228
end)
258-
end)
259-
|> prepare_schema()
260-
|> (&struct_from_map(Schema, &1)).()
261-
|> prop_to_struct(:properties, Schemas)
262-
|> manage_additional_properties()
263-
|> prop_to_struct(:externalDocs, ExternalDocumentation)
264-
|> add_extensions(map)
265-
end
229+
|> prepare_schema()
230+
|> (&struct_from_map(Schema, &1)).()
231+
|> prop_to_struct(:items, Schema)
232+
|> prop_to_struct(:xml, Xml)
233+
|> prop_to_struct(:anyOf, Schemas)
234+
|> prop_to_struct(:oneOf, Schemas)
235+
|> prop_to_struct(:allOf, Schemas)
236+
|> prop_to_struct(:discriminator, Discriminator)
237+
|> prop_to_struct(:properties, Schemas)
238+
|> manage_additional_properties()
239+
|> prop_to_struct(:externalDocs, ExternalDocumentation)
240+
|> prop_to_struct(:not, Schema)
241+
|> add_extensions(map)
242+
|> dbg
243+
244+
if a.properties == %{} do
245+
dbg(a.properties)
246+
dbg(map["properties"])
247+
raise map
248+
# dbg(map)
249+
end
266250

267-
defp to_struct(%{"not" => _valid_schemas} = map, Schema) do
268-
Schema
269-
|> struct_from_map(map)
270-
|> prop_to_struct(:not, Schema)
271-
|> add_extensions(map)
251+
a
272252
end
273253

274254
defp to_struct(map, Schemas) when is_map(map), do: embedded_ref_or_struct(map, Schema)

test/support/encoded_schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@
538538
"required": [
539539
"data"
540540
],
541-
"type": "object"
541+
"type": ["object", "null"]
542542
}
543543
}
544544
}

0 commit comments

Comments
 (0)