I have a JSON schema that will produce data like (per line):
{"block_type": "page-break-1.0", "break_type": "soft"}
{"block_type": "custom-section-1.0", "name": "Some section", "pk": "uuid"}
{"block_type": "custom-section-template-1.0", "name": "Some section"}
This was my first attempt this:
module LevelId = {
type t = string
}
module Block = {
type t = {uuid: string}
}
module PageBreak = {
type t = {...Block.t, break_type: [#soft | #hard]}
}
module CustomSection = {
type t = {...Block.t, name: string, level_id: LevelId.t}
}
module CustomSectionTemplate = {
type t = {...Block.t, name: string}
}
module ReportBlock = {
@tag("block_type")
type t =
| @as("page-break-1.0") PageBreak(PageBreak.t)
| @as("custom-section-1.0") CustomSection(CustomSection.t)
}
module ReportTemplateBlock = {
@tag("block_type")
type t =
| @as("page-break-1.0") PageBreak(PageBreak.t)
| @as("custom-section-template-1.0")
CustomSectionTemplate(CustomSectionTemplate.t)
}
module Examples = {
let x: ReportBlock.t = PageBreak({uuid: "1", break_type: #soft})
let y: ReportBlock.t = CustomSection({
uuid: "2",
name: "Some section",
level_id: "0000-0000",
})
let x1: ReportTemplateBlock.t = PageBreak({uuid: "3", break_type: #soft})
let y1: ReportTemplateBlock.t = CustomSectionTemplate({
uuid: "4",
name: "Some section",
})
}
However that would not match the JSON data.
I tried to (mis)use the @unboxed
and breaks the tag:
module ReportBlock = {
@tag("block_type")
type t =
| @as("page-break-1.0") @unboxed PageBreak(PageBreak.t)
| @as("custom-section-1.0") @unboxed CustomSection(CustomSection.t)
}
That produces JS records without the block_type
:
var Examples_x = {
uuid: "1",
break_type: "soft"
};
var Examples_y = {
uuid: "2",
name: "Some section",
level_id: "0000-0000"
};
The only “solution” I have now is to inline the types like here:
module ReportBlock = {
@tag("block_type")
type t =
| @as("page-break-1.0") PageBreak({uuid: string, break_type: [#soft | #hard]})
| @as("custom-section-1.0") CustomSection({uuid: string, name: string, level_id: string})
}
But that would make the types non-shared between the two main types ReportBlock.t
, and ReportTemplateBlock.t
.
Is there a way to overcome this?