But life may not that easy, some response would be complicated, and in go world, we use tools like json-to-to, and generate go struct like:
type AutoGenerated struct {
Rc int `json:"rc"`
Rt int `json:"rt"`
Svr int `json:"svr"`
Lt int `json:"lt"`
Full int `json:"full"`
Dlmkts string `json:"dlmkts"`
Data struct {
Total int `json:"total"`
Diff []struct {
F9 int `json:"f9"`
F12 string `json:"f12"`
F13 int `json:"f13"`
F14 string `json:"f14"`
F20 int64 `json:"f20"`
F23 int `json:"f23"`
F58 float64 `json:"f58"`
F130 float64 `json:"f130"`
F131 float64 `json:"f131"`
F132 float64 `json:"f132"`
F133 float64 `json:"f133"`
F134 string `json:"f134"`
F137 float64 `json:"f137"`
F138 float64 `json:"f138"`
F152 int `json:"f152"`
F1020 int `json:"f1020"`
F1113 int `json:"f1113"`
F1045 int `json:"f1045"`
F1009 int `json:"f1009"`
F1023 int `json:"f1023"`
F1049 int `json:"f1049"`
F1129 int `json:"f1129"`
F1037 int `json:"f1037"`
F1135 int `json:"f1135"`
F1115 int `json:"f1115"`
F1058 int `json:"f1058"`
F1132 int `json:"f1132"`
F1130 int `json:"f1130"`
F1131 int `json:"f1131"`
F1137 int `json:"f1137"`
F1133 int `json:"f1133"`
F1138 int `json:"f1138"`
F3020 int `json:"f3020"`
F3113 int `json:"f3113"`
F3045 int `json:"f3045"`
F3009 int `json:"f3009"`
F3023 int `json:"f3023"`
F3049 int `json:"f3049"`
F3129 int `json:"f3129"`
F3037 int `json:"f3037"`
F3135 int `json:"f3135"`
F3115 int `json:"f3115"`
F3058 int `json:"f3058"`
F3132 int `json:"f3132"`
F3130 int `json:"f3130"`
F3131 int `json:"f3131"`
F3137 int `json:"f3137"`
F3133 int `json:"f3133"`
F3138 int `json:"f3138"`
} `json:"diff"`
} `json:"data"`
}
I was wondering if there is any tool like this in ReScript world?
It does not exactly generate types though. It generates something that is a little more expressive than normal types, thought it’s pretty evident what the underlying type would look like. Just, there’s no automation to convert that into strictly a ReScript type.
yeah I need to find time to put together a good sample project, probably in that benchmark repo, for atd. Decoders with code are great but having something generate that code for you is even better
The atdgen runtime is based on bs-json, and I don’t own it. I just took over maintenance of the project to publish atdgen executables on NPM.
The benifit of decoders with code, is that you can describe data migrations from one data structure to another. While with codegened decoders it should be done in additional step. But I 100% agree that the DX of using something like decco is so much better
@spice
type t = {
@spice.key("spice-label") label: string,
@spice.key("spice-value") value: int,
}
let sample = Js.Dict.empty()
sample->Js.Dict.set("spice-label", Js.Json.string("sample"))
sample->Js.Dict.set("spice-value", Js.Json.number(1.0))
let sampleJson = sample->Js.Json.object_
let sampleRecord: t = {
label: "sample",
value: 1,
}
let encoded = sampleRecord->Records.t_encode // sampleJson
let decoded = sampleJson->Records.t_decode // Belt.Result.Ok(sampleRecord)
Basically I just copy-and-paste the demo, there’s an error:
npm run start (master)rescript-project-template
> rescript-project-template@0.0.1 start
> rescript build -w
>>>> Start compiling
Staled output removed
rescript: [2/2] src/r101.cmj
FAILED: src/r101.cmj
We've found a bug for you!
/Users/hellotli/Downloads/todel/rescript-project-template/src/r101.res:18:29-44
16 │
17 │
18 │ let encoded = sampleRecord->Records.t_encode // sampleJson
19 │
20 │ let decoded = sampleJson->Records.t_decode // Belt.Result.Ok(sampleReco
│ rd)
The module or file Records can't be found.
- If it's a third-party dependency:
- Did you list it in bsconfig.json?
- Did you run `rescript build` instead of `rescript build -with-deps`
(latter builds third-parties)?
- Did you include the file's directory in bsconfig.json?
FAILED: cannot make progress due to previous errors.
>>>> Finish compiling(exit: 1)
OOPS, I need a so called Records here, after went through the code base, I found a Records.res in
I download the file into src folder, and got another error
decco and ppx_spice are just ppx which generates the encode and decode fn automatically based on the given type. So if you want to parse a json data to the typed data, you need to define the type first.
@spice
type t = {
name: string,
candidates: array<int>
}
Make sure the values of name and candidates are not nullable, if it is you need to define them as optional.