Skip to content

Commit a09db06

Browse files
Fixes issue with printing correct pipeline when parsing optional enum/union types
1 parent 00d6593 commit a09db06

File tree

9 files changed

+89
-33
lines changed

9 files changed

+89
-33
lines changed

examples/example-input-json-schemas/circle.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@
1414
"color": {
1515
"$ref": "http://example.com/definitions.json#color"
1616
}
17-
}
17+
},
18+
"required": ["center", "radius"]
1819
}

lib/printers/object_printer.ex

+72-27
Original file line numberDiff line numberDiff line change
@@ -164,35 +164,44 @@ defmodule JS2E.Printers.ObjectPrinter do
164164

165165
decoder_name = print_decoder_name(property_type)
166166

167+
is_required = property_name in required
168+
167169
cond do
168-
union_type?(property_type) ->
169-
print_custom_clause(property_name, decoder_name)
170+
union_type?(property_type) || one_of_type?(property_type) ->
171+
print_union_clause(property_name, decoder_name, is_required)
172+
173+
enum_type?(property_type) ->
174+
property_type_decoder =
175+
property_type.type
176+
|> determine_primitive_type_decoder()
170177

171-
property_name in required ->
172-
print_required_clause(property_name, decoder_name)
178+
print_enum_clause(property_name, property_type_decoder,
179+
decoder_name, is_required)
173180

174181
true ->
175-
print_optional_clause(property_name, decoder_name)
182+
print_normal_clause(property_name, decoder_name, is_required)
176183
end
177184
end
178185

179-
@spec print_decoder_name(Types.typeDefinition) :: String.t
180-
defp print_decoder_name(property_type) do
186+
@spec determine_primitive_type_decoder(String.t) :: String.t
187+
defp determine_primitive_type_decoder(property_type_value) do
188+
case property_type_value do
189+
"integer" ->
190+
"int"
181191

182-
if primitive_type?(property_type) do
183-
property_type_value = property_type.type
184-
185-
case property_type_value do
186-
"integer" ->
187-
"int"
192+
"number" ->
193+
"float"
188194

189-
"number" ->
190-
"float"
195+
_ ->
196+
property_type_value
197+
end
198+
end
191199

192-
_ ->
193-
property_type_value
194-
end
200+
@spec print_decoder_name(Types.typeDefinition) :: String.t
201+
defp print_decoder_name(property_type) do
195202

203+
if primitive_type?(property_type) do
204+
determine_primitive_type_decoder(property_type.type)
196205
else
197206

198207
property_type_name = property_type.name
@@ -209,26 +218,62 @@ defmodule JS2E.Printers.ObjectPrinter do
209218
Util.get_string_name(type) == "PrimitiveType"
210219
end
211220

221+
defp enum_type?(type) do
222+
Util.get_string_name(type) == "EnumType"
223+
end
224+
225+
defp one_of_type?(type) do
226+
Util.get_string_name(type) == "OneOfType"
227+
end
228+
212229
defp union_type?(type) do
213230
Util.get_string_name(type) == "UnionType"
214231
end
215232

216-
defp print_custom_clause(property_name, decoder_name) do
233+
defp print_union_clause(property_name, decoder_name, is_required) do
217234
double_indent = Util.indent(2)
218-
"#{double_indent}|> " <>
219-
"custom (field \"#{property_name}\" #{decoder_name})"
235+
236+
if is_required do
237+
"#{double_indent}|> " <>
238+
"required \"#{property_name}\" #{decoder_name}"
239+
240+
else
241+
"#{double_indent}|> " <>
242+
"optional \"#{property_name}\" (nullable #{decoder_name}) Nothing"
243+
end
220244
end
221245

222-
defp print_required_clause(property_name, decoder_name) do
246+
defp print_enum_clause(
247+
property_name,
248+
property_type_decoder,
249+
decoder_name,
250+
is_required) do
251+
223252
double_indent = Util.indent(2)
224-
"#{double_indent}|> " <>
225-
"required \"#{property_name}\" #{decoder_name}"
253+
254+
if is_required do
255+
"#{double_indent}|> " <>
256+
"required \"#{property_name}\" (#{property_type_decoder} |> " <>
257+
"andThen #{decoder_name})"
258+
259+
else
260+
"#{double_indent}|> " <>
261+
"optional \"#{property_name}\" (#{property_type_decoder} |> " <>
262+
"andThen #{decoder_name} |> maybe) Nothing"
263+
end
226264
end
227265

228-
defp print_optional_clause(property_name, decoder_name) do
266+
defp print_normal_clause(property_name, decoder_name, is_required) do
229267
double_indent = Util.indent(2)
230-
"#{double_indent}|> " <>
231-
"optional \"#{property_name}\" (nullable #{decoder_name}) Nothing"
268+
269+
if is_required do
270+
"#{double_indent}|> " <>
271+
"required \"#{property_name}\" #{decoder_name}"
272+
273+
else
274+
"#{double_indent}|> " <>
275+
"optional \"#{property_name}\" (nullable #{decoder_name}) Nothing"
276+
end
232277
end
233278

234279
end

lib/printers/preamble_printer.ex

+2
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ defmodule JS2E.Printers.PreamblePrinter do
3131
import Json.Decode as Decode
3232
exposing
3333
( int
34+
, float
3435
, string
3536
, succeed
3637
, fail
3738
, list
3839
, map
40+
, maybe
3941
, field
4042
, at
4143
, andThen

lib/types/enum_type.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ defmodule JS2E.Types.EnumType do
5959
6060
- Usage
6161
62-
|> custom (field "color" string |> andThen colorDecoder)
62+
|> required "color" (string |> andThen colorDecoder)
6363
6464
"""
6565

lib/types/one_of_type.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ defmodule JS2E.Types.OneOfType do
4343
4444
- Usage
4545
46-
|> custom (field "shape" shapeDecoder)
46+
|> required "shape" shapeDecoder
4747
4848
"""
4949

lib/types/union_type.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ defmodule JS2E.Types.UnionType do
3434
3535
- Usage
3636
37-
|> custom (field "favoriteNumber" favoriteNumberDecoder)
37+
|> required "favoriteNumber" favoriteNumberDecoder
3838
3939
"""
4040

mix.exs

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ defmodule JS2.Mixfile do
66
version: "1.0.0",
77
elixir: "~> 1.4",
88
deps: deps(),
9+
build_embedded: Mix.env == :prod,
10+
start_permanent: Mix.env == :prod,
11+
12+
# Dialyxir
913
dialyzer: [plt_add_deps: :project],
1014

1115
# Docs

test/printers/external_references_test.exs

+5-1
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,13 @@ defmodule JS2ETest.Printers.ExternalReferences do
117117
import Json.Decode as Decode
118118
exposing
119119
( int
120+
, float
120121
, string
121122
, succeed
122123
, fail
123124
, list
124125
, map
126+
, maybe
125127
, field
126128
, at
127129
, andThen
@@ -156,7 +158,7 @@ defmodule JS2ETest.Printers.ExternalReferences do
156158
circleDecoder =
157159
decode Circle
158160
|> optional "center" (nullable pointDecoder) Nothing
159-
|> optional "color" (nullable colorDecoder) Nothing
161+
|> optional "color" (string |> andThen colorDecoder |> maybe) Nothing
160162
|> optional "radius" (nullable float) Nothing
161163
"""
162164

@@ -172,11 +174,13 @@ defmodule JS2ETest.Printers.ExternalReferences do
172174
import Json.Decode as Decode
173175
exposing
174176
( int
177+
, float
175178
, string
176179
, succeed
177180
, fail
178181
, list
179182
, map
183+
, maybe
180184
, field
181185
, at
182186
, andThen

test/printers/object_printer_test.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ defmodule JS2ETest.Printers.ObjectPrinter do
8686
circleDecoder : Decoder Circle
8787
circleDecoder =
8888
decode Circle
89-
|> required "color" colorDecoder
89+
|> required "color" (string |> andThen colorDecoder)
9090
|> required "radius" float
9191
|> optional "title" (nullable string) Nothing
9292
"""

0 commit comments

Comments
 (0)