Hi,
The json-data-encoding
library is definitely capable of defining encodings for this type. It can be a bit difficult to get into, so here is a quick walkthrough of a simple solution. Don’t hesitate to ask if you have more questions!
Prelude
First, setting up some minimal build environment. This simple dune
file lets you compile the file, but also can get you all the Merlin
features working.
$ cat dune
(executables
(names jde)
(libraries json-data-encoding)
(flags :standard))
Then the main file, starting with the exact copy of your type declaration:
$ cat jde.ml
type t = {
self: t option;
int32f: int32;
int64f: int64;
boolf: bool;
}
We need to do one last preparatory work: define an encoding for int64
. This is necessary because json-data-encoding
doesn’t provide an encoding for that type. Why? Because Javascript represents numbers as floats and floats are only dense enough to represent integers up to int53 after which it just misses more and more ints as you get higher.
I’m going for a dead simple representation that’s not ideal. The string representation of it is going to be relatively compact, but the encoding/decoding uses conversion functions, some form of parsing, etc. You can maybe do better with, say, a pair of int32.
let int64 =
let open Json_encoding in
conv
Int64.to_string
Int64.of_string
string
Core: mu
With that set up, we can define the encoding directly. The use of mu
can be weird, but the core idea is: you give it a name (as a string) just so it has a name for it internally, and then you give it a function where the single parameter is a stand in for the whole of the body.
There’s also a necessary step where you transform your record into a tuple. This is necessary because the library provides encodings for tuples which are a generic enough form of data that it can be manipulated by libraries.
let encoding : t Json_encoding.encoding =
let open Json_encoding in
mu
"self"
(fun self ->
conv
(fun {self; int32f; int64f; boolf} -> (self, int32f, int64f, boolf))
(fun (self, int32f, int64f, boolf) -> {self; int32f; int64f; boolf})
@@ obj4
(opt "self" self)
(req "int32f" int32)
(req "int64f" int64)
(req "boolf" bool))
Postlude
You can get the schema and then print it very easily as follows:
let schema =
Json_encoding.schema encoding
let () =
Format.printf
"%a\n%!"
(Json_repr.pp (module Json_repr.Ezjsonm))
(Json_schema.to_json schema)
And then you can just compile and run:
$ dune build
$ ./_build/default/jde.exe
{ "$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/self",
"definitions":
{ "self":
{ "type": "object",
"properties":
{ "self": { "$ref": "#/definitions/self" },
"int32f":
{ "type": "integer", "minimum": -2147483648,
"maximum": 2147483647 }, "int64f": { "type": "string" },
"boolf": { "type": "boolean" } },
"required": [ "boolf", "int64f", "int32f" ],
"additionalProperties": false } } }