Skip to content

Commit 28a7c55

Browse files
Qualified references (#43)
Closes #39 by adding fully qualified names in the generated Elm code when referencing definitions from other modules. * Adds 'module' to schema definitions, * passes the schema definition context - instead of the type dictionary - to each printer function, * uses fully qualified names when referencing types, encoders and decoders from other modules in the generated Elm code, * removes the explicit import of types, decoders and encoders from other modules in the generated Elm code. Now just import the module and nothing else, * adds support for the 'title' property in the schema root object, * removes some code redundancy, and * updates readme with new elm output.
1 parent bbbd5a2 commit 28a7c55

32 files changed

+822
-759
lines changed

README.md

+70-10
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,7 @@ module Domain.Definitions exposing (..)
7070

7171
import Json.Decode as Decode
7272
exposing
73-
( float
74-
, int
75-
, string
76-
, list
77-
, succeed
73+
( succeed
7874
, fail
7975
, map
8076
, maybe
@@ -95,10 +91,6 @@ import Json.Decode.Pipeline
9591
import Json.Encode as Encode
9692
exposing
9793
( Value
98-
, float
99-
, int
100-
, string
101-
, list
10294
, object
10395
)
10496

@@ -198,10 +190,78 @@ that have references across files, e.g.
198190
}
199191
```
200192

201-
then the corresponding Elm file, `Domain.Circle`, will import the
193+
then the corresponding Elm file, `Domain/Circle.elm`, will import the
202194
definitions (types, encoders and decoders) from the other Elm module,
203195
`Domain/Definitions.elm`.
204196

197+
``` elm
198+
module Domain.Circle exposing (..)
199+
200+
-- Schema for a circle shape
201+
202+
import Json.Decode as Decode
203+
exposing
204+
( succeed
205+
, fail
206+
, map
207+
, maybe
208+
, field
209+
, at
210+
, andThen
211+
, oneOf
212+
, nullable
213+
, Decoder
214+
)
215+
import Json.Decode.Pipeline
216+
exposing
217+
( decode
218+
, required
219+
, optional
220+
, custom
221+
)
222+
import Json.Encode as Encode
223+
exposing
224+
( Value
225+
, object
226+
)
227+
import Domain.Definitions
228+
229+
230+
type alias Circle =
231+
{ center : Domain.Definitions.Point
232+
, color : Maybe Domain.Definitions.Color
233+
, radius : Float
234+
}
235+
236+
237+
circleDecoder : Decoder Circle
238+
circleDecoder =
239+
decode Circle
240+
|> required "center" Domain.Definitions.pointDecoder
241+
|> optional "color" (Decode.string |> andThen Domain.Definitions.colorDecoder |> maybe) Nothing
242+
|> required "radius" Decode.float
243+
244+
245+
encodeCircle : Circle -> Value
246+
encodeCircle circle =
247+
let
248+
center =
249+
[ ( "center", Domain.Definitions.encodePoint circle.center ) ]
250+
251+
color =
252+
case circle.color of
253+
Just color ->
254+
[ ( "color", Domain.Definitions.encodeColor color ) ]
255+
256+
Nothing ->
257+
[]
258+
259+
radius =
260+
[ ( "radius", Encode.float circle.radius ) ]
261+
in
262+
object <| center ++ color ++ radius
263+
```
264+
205265
## Tests
206266

207267
Run the standard mix task

examples/example-output-elm-code/Domain/Circle.elm

+19-32
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ module Domain.Circle exposing (..)
44

55
import Json.Decode as Decode
66
exposing
7-
( float
8-
, int
9-
, string
10-
, list
11-
, succeed
7+
( succeed
128
, fail
139
, map
1410
, maybe
@@ -29,53 +25,44 @@ import Json.Decode.Pipeline
2925
import Json.Encode as Encode
3026
exposing
3127
( Value
32-
, float
33-
, int
34-
, string
35-
, list
3628
, object
3729
)
3830
import Domain.Definitions
39-
exposing
40-
( Color
41-
, colorDecoder
42-
, encodeColor
43-
, Point
44-
, pointDecoder
45-
, encodePoint
46-
)
4731

4832

49-
type alias Root =
50-
{ center : Point
51-
, color : Maybe Color
33+
type alias Circle =
34+
{ center : Domain.Definitions.Point
35+
, color : Maybe Domain.Definitions.Color
5236
, radius : Float
5337
}
5438

5539

56-
rootDecoder : Decoder Root
57-
rootDecoder =
58-
decode Root
59-
|> required "center" pointDecoder
60-
|> optional "color" (Decode.string |> andThen colorDecoder |> maybe) Nothing
40+
circleDecoder : Decoder Circle
41+
circleDecoder =
42+
decode Circle
43+
|> required "center" Domain.Definitions.pointDecoder
44+
|> optional "color" (Decode.string |> andThen Domain.Definitions.colorDecoder |> maybe) Nothing
6145
|> required "radius" Decode.float
6246

6347

64-
encodeRoot : Root -> Value
65-
encodeRoot root =
48+
encodeCircle : Circle -> Value
49+
encodeCircle circle =
6650
let
6751
center =
68-
[ ( "center", encodePoint root.center ) ]
52+
[ ( "center", Domain.Definitions.encodePoint circle.center ) ]
6953

7054
color =
71-
case root.color of
55+
case circle.color of
7256
Just color ->
73-
[ ( "color", encodeColor color ) ]
57+
[ ( "color", Domain.Definitions.encodeColor color ) ]
7458

7559
Nothing ->
7660
[]
7761

7862
radius =
79-
[ ( "radius", Encode.float root.radius ) ]
63+
[ ( "radius", Encode.float circle.radius ) ]
8064
in
81-
object <| center ++ color ++ radius
65+
object <|
66+
center
67+
++ color
68+
++ radius

examples/example-output-elm-code/Domain/Definitions.elm

+3-10
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ module Domain.Definitions exposing (..)
44

55
import Json.Decode as Decode
66
exposing
7-
( float
8-
, int
9-
, string
10-
, list
11-
, succeed
7+
( succeed
128
, fail
139
, map
1410
, maybe
@@ -29,10 +25,6 @@ import Json.Decode.Pipeline
2925
import Json.Encode as Encode
3026
exposing
3127
( Value
32-
, float
33-
, int
34-
, string
35-
, list
3628
, object
3729
)
3830

@@ -101,4 +93,5 @@ encodePoint point =
10193
y =
10294
[ ( "y", Encode.float point.y ) ]
10395
in
104-
object <| x ++ y
96+
object <|
97+
x ++ y

lib/js2e.ex

+2-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ defmodule JS2E do
105105
@spec generate([String.t], String.t) :: :ok
106106
def generate(json_schema_paths, module_name) do
107107

108-
schema_dict = Parser.parse_schema_files(json_schema_paths)
109-
printed_schemas = Printer.print_schemas(schema_dict, module_name)
108+
schema_dict = Parser.parse_schema_files(json_schema_paths, module_name)
109+
printed_schemas = Printer.print_schemas(schema_dict)
110110

111111
printed_schemas
112112
|> Enum.each(fn{file_path, file_content} ->

lib/parser.ex

+9-9
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,27 @@ defmodule JS2E.Parser do
1919
"http://json-schema.org/draft-04/schema"
2020
]
2121

22-
@spec parse_schema_files([String.t]) :: Types.schemaDictionary
23-
def parse_schema_files(json_schema_paths) do
22+
@spec parse_schema_files([String.t], String.t) :: Types.schemaDictionary
23+
def parse_schema_files(json_schema_paths, module_name) do
2424
json_schema_paths
2525
|> Enum.reduce(%{}, fn (json_schema_path, schema_dict) ->
2626

2727
json_schema_path
28-
|> parse_schema_file
28+
|> parse_schema_file(module_name)
2929
|> Map.merge(schema_dict)
3030
end)
3131
end
3232

33-
@spec parse_schema_file(String.t) :: Types.schemaDictionary
34-
def parse_schema_file(json_schema_path) do
33+
@spec parse_schema_file(String.t, String.t) :: Types.schemaDictionary
34+
def parse_schema_file(json_schema_path, module_name) do
3535
json_schema_path
3636
|> File.read!
3737
|> Poison.decode!
38-
|> parse_schema
38+
|> parse_schema(module_name)
3939
end
4040

41-
@spec parse_schema(map) :: Types.schemaDictionary
42-
def parse_schema(schema_root_node) do
41+
@spec parse_schema(map, String.t) :: Types.schemaDictionary
42+
def parse_schema(schema_root_node, module_name) do
4343

4444
if not supported_schema_version?(schema_root_node) do
4545
exit(:bad_version)
@@ -64,7 +64,7 @@ defmodule JS2E.Parser do
6464
|> Map.merge(root, handle_conflict)
6565

6666
%{to_string(schema_id) =>
67-
SchemaDefinition.new(schema_id, title, description, types)}
67+
SchemaDefinition.new(schema_id, title, module_name, description, types)}
6868
end
6969

7070
@spec parse_schema_id(any) :: {:ok, URI.t} | {:error, String.t}

0 commit comments

Comments
 (0)