Skip to content

Commit f42ba61

Browse files
committed
Add some support for oneOf/anyOf
1 parent 44964bd commit f42ba61

21 files changed

Lines changed: 447 additions & 3 deletions

File tree

.github/workflows/samples-ocaml.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ on:
55
paths:
66
- 'samples/client/petstore/ocaml/**'
77
- 'samples/client/petstore/ocaml-fake-petstore/**'
8+
- 'samples/client/petstore/ocaml-oneOf/**'
89
pull_request:
910
paths:
1011
- 'samples/client/petstore/ocaml/**'
1112
- 'samples/client/petstore/ocaml-fake-petstore/**'
13+
- 'samples/client/petstore/ocaml-oneOf/**'
1214

1315
jobs:
1416
build:
@@ -20,6 +22,7 @@ jobs:
2022
sample:
2123
- 'samples/client/petstore/ocaml/'
2224
- 'samples/client/petstore/ocaml-fake-petstore/'
25+
- 'samples/client/petstore/ocaml-oneOf/'
2326
steps:
2427
- uses: actions/checkout@v5
2528
- name: Set-up OCaml

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ samples/openapi3/client/petstore/go/privatekey.pem
297297
## OCaml
298298
samples/client/petstore/ocaml/_build/
299299
samples/client/petstore/ocaml-fake-petstore/_build/
300+
samples/client/petstore/ocaml-oneOf/_build/
300301

301302
# jetbrain http client
302303
samples/client/jetbrains/adyen/checkout71/http/client/Apis/http-client.private.env.json

bin/configs/ocaml-oneOf.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
generatorName: ocaml
2+
outputDir: samples/client/petstore/ocaml-oneOf
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOf_primitive.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/ocaml
5+
additionalProperties:
6+
packageName: petstore_client

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/OCamlClientCodegen.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,15 @@ public OCamlClientCodegen() {
9595
.excludeSchemaSupportFeatures(
9696
SchemaSupportFeature.Polymorphism
9797
)
98+
.includeSchemaSupportFeatures(
99+
SchemaSupportFeature.oneOf,
100+
SchemaSupportFeature.anyOf
101+
)
98102
.includeClientModificationFeatures(
99103
ClientModificationFeature.BasePath
100104
)
101105
);
102106

103-
104107
outputFolder = "generated-code/ocaml";
105108
modelTemplateFiles.put("model.mustache", ".ml");
106109

@@ -193,7 +196,6 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> supero
193196
List<String> toRemove = new ArrayList<>();
194197

195198
for (Map.Entry<String, ModelsMap> modelEntry : superobjs.entrySet()) {
196-
// process enum in models
197199
List<ModelMap> models = modelEntry.getValue().getModels();
198200
for (ModelMap mo : models) {
199201
CodegenModel cm = mo.getModel();
@@ -210,6 +212,15 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> supero
210212
enrichPropertiesWithEnumDefaultValues(cm.getVars());
211213
enrichPropertiesWithEnumDefaultValues(cm.getParentVars());
212214
}
215+
216+
if (!cm.oneOf.isEmpty()) {
217+
// Add a boolean if it is a `oneOf`, because Mustache does not let us check if a list is non-empty
218+
cm.getVendorExtensions().put("x-ocaml-isOneOf", true);
219+
}
220+
if (!cm.anyOf.isEmpty()) {
221+
// Add a boolean if it is a `anyOf`, because Mustache does not let us check if a list is non-empty
222+
cm.getVendorExtensions().put("x-ocaml-isAnyOf", true);
223+
}
213224
}
214225
}
215226

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
type t =
2+
{{#composedSchemas.anyOf}}
3+
| {{{nameInPascalCase}}} of {{{dataType}}}
4+
{{/composedSchemas.anyOf}}
5+
[@@deriving show, eq];;
6+
7+
let to_yojson = function
8+
{{#composedSchemas.anyOf}}
9+
| {{{nameInPascalCase}}} v -> [%to_yojson: {{{ datatypeWithEnum }}}] v
10+
{{/composedSchemas.anyOf}}
11+
12+
(* Manual implementations because the derived one encodes into a tuple list where the first element is the constructor name. *)
13+
14+
let of_yojson json =
15+
[
16+
{{#composedSchemas.anyOf}}
17+
[%of_yojson: {{{ datatypeWithEnum }}}] json
18+
|> Stdlib.Result.to_option
19+
|> Stdlib.Option.map (fun v -> {{{nameInPascalCase}}} v);
20+
{{/composedSchemas.anyOf}}
21+
]
22+
|> Stdlib.List.filter_map (Fun.id)
23+
|> function
24+
| t :: _ -> Ok t (* Return the first successful parsing. *)
25+
| [] -> Error ("Failed to parse JSON " ^ Yojson.Safe.show json ^ " into a value of type {{{ classname }}}")
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
type t =
2+
{{#composedSchemas.oneOf}}
3+
| {{{nameInPascalCase}}} of {{{dataType}}}
4+
{{/composedSchemas.oneOf}}
5+
[@@deriving show, eq];;
6+
7+
let to_yojson = function
8+
{{#composedSchemas.oneOf}}
9+
| {{{nameInPascalCase}}} v -> [%to_yojson: {{{ datatypeWithEnum }}}] v
10+
{{/composedSchemas.oneOf}}
11+
12+
(* Manual implementations because the derived one encodes into a tuple list where the first element is the constructor name. *)
13+
14+
let of_yojson json =
15+
[
16+
{{#composedSchemas.oneOf}}
17+
[%of_yojson: {{{ datatypeWithEnum }}}] json
18+
|> Stdlib.Result.to_option
19+
|> Stdlib.Option.map (fun v -> {{{nameInPascalCase}}} v);
20+
{{/composedSchemas.oneOf}}
21+
]
22+
|> Stdlib.List.filter_map (Fun.id)
23+
|> function
24+
| [t] -> Ok t
25+
| [] -> Error ("Failed to parse JSON " ^ Yojson.Safe.show json ^ " into a value of type {{{ classname }}}")
26+
| ts -> let parsed_ts = ts
27+
|> Stdlib.List.map show
28+
|> Stdlib.String.concat " | "
29+
in Error ("Failed to parse JSON " ^ Yojson.Safe.show json ^ " into a value of type {{{ classname }}}: oneOf should only succeed on one parser, but the JSON was parsed into [" ^ parsed_ts ^ "]")

modules/openapi-generator/src/main/resources/ocaml/model.mustache

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,17 @@
1010
{{/description}}
1111

1212
{{^isEnum}}
13-
{{>model-record}}
13+
{{#vendorExtensions.x-ocaml-isOneOf}}
14+
{{>model-one-of}}
15+
{{/vendorExtensions.x-ocaml-isOneOf}}
16+
17+
{{#vendorExtensions.x-ocaml-isAnyOf}}
18+
{{>model-any-of}}
19+
{{/vendorExtensions.x-ocaml-isAnyOf}}
20+
21+
{{^vendorExtensions.x-ocaml-isOneOf}}{{^vendorExtensions.x-ocaml-isAnyOf}}
22+
{{>model-record}}
23+
{{/vendorExtensions.x-ocaml-isAnyOf}}{{/vendorExtensions.x-ocaml-isOneOf}}
1424
{{/isEnum}}
1525

1626
{{/model}}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.openapi-generator-ignore
2+
README.md
3+
dune
4+
dune-project
5+
petstore_client.opam
6+
src/apis/default_api.ml
7+
src/apis/default_api.mli
8+
src/models/child.ml
9+
src/models/example.ml
10+
src/support/enums.ml
11+
src/support/jsonSupport.ml
12+
src/support/request.ml
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.15.0-SNAPSHOT

0 commit comments

Comments
 (0)