Skip to content

Commit

Permalink
jsonschema: support non string enums
Browse files Browse the repository at this point in the history
  • Loading branch information
Khady committed Feb 27, 2024
1 parent d4fdb0d commit 0d6cb59
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
25 changes: 23 additions & 2 deletions lib/generator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,16 @@ let rec process_schema_type ~ancestors (schema : schema) =
| Some schemas -> process_one_of ~ancestors schemas
| None ->
match schema.enum, schema.typ with
| Some enums, Some String -> process_enums enums
| Some enums, Some String -> process_string_enums enums
| Some _, Some Integer ->
(* this is more lenient than it should *)
maybe_nullable (process_int_type schema)
| Some _, Some Number ->
(* this is more lenient than it should *)
maybe_nullable "float"
| Some _, Some Boolean ->
(* this is more lenient than it should *)
maybe_nullable "bool"
| Some _, _ -> failwith "only string enums are supported"
| None, _ ->
match schema.typ with
Expand Down Expand Up @@ -217,7 +226,19 @@ and process_one_of ~ancestors (schemas_or_refs : schema or_ref list) =
let variants = List.map make_one_of_variant schemas_or_refs |> String.concat "\n" in
sprintf "[\n%s\n] <json adapter.ocaml=\"Jsonschema2atd_runtime.Adapter.One_of\">" variants

and process_enums enums =
and process_string_enums enums =
let enums =
List.map
(function
| `String s -> s
| value ->
failwith
(sprintf "Invalid value %s in string enum %s" (Yojson.Basic.to_string value)
(Yojson.Basic.to_string (`List enums))
)
)
enums
in
let make_enum_variant value = sprintf {| | %s <json name="%s">|} (variant_name value) value in
let variants = List.map make_enum_variant enums |> String.concat "\n" in
sprintf "[\n%s\n]" variants
Expand Down
2 changes: 1 addition & 1 deletion lib/json_schema.atd
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type schema = {

(* 6.1 validation for any instance type *)
~typ <json name="type">: typ nullable;
~enum : string nonempty_list nullable;
~enum : json nonempty_list nullable;

(* 6.2 validation for numeric instances *)
(* ~multiple_of <json name="multipleOf">: float nullable; *)
Expand Down
36 changes: 36 additions & 0 deletions tests/mocks/jsonschema_enums.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"myProperty": {
"type": "string",
"enum": [
"foo",
"bar"
]
},
"myPropertyInt": {
"type": "integer",
"enum": [
1,
2
]
},
"myPropertyNumber": {
"type": "number",
"enum": [
1.2,
2.3
]
},
"myPropertyBool": {
"type": "boolean",
"enum": [
true
]
}
},
"required": [
"myProperty"
]
}
24 changes: 24 additions & 0 deletions tests/smoke.t
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,27 @@ Generate ATD out of JSON Schema that uses references
?ee : address option;
?ff : address option;
}

Generate ATD out of JSON Schema that uses enums
$ jsonschema2atd --format=jsonschema ./mocks/jsonschema_enums.json
(* Generated by jsonschema2atd *)
type json <ocaml module="Yojson.Basic" t="t"> = abstract
type int64 = int <ocaml repr="int64">

type rootMyProperty = [
| Foo <json name="foo">
| Bar <json name="bar">
]

type rootMyPropertyInt = int

type rootMyPropertyNumber = float

type rootMyPropertyBool = bool

type root = {
myProperty : rootMyProperty;
?myPropertyInt : rootMyPropertyInt option;
?myPropertyNumber : rootMyPropertyNumber option;
?myPropertyBool : rootMyPropertyBool option;
}

0 comments on commit 0d6cb59

Please sign in to comment.