@greenlabs/ppx-spice 0.2.8 → 0.3.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -1
- package/README.md +7 -5
- package/greenlabs-ppx-spice-0.3.0-next.0.tgz +0 -0
- package/package.json +5 -3
- package/ppx-linux.exe +0 -0
- package/ppx-osx.exe +0 -0
- package/ppx-windows.exe +0 -0
- package/rescript.json +3 -7
- package/src/rescript/Spice.res +65 -60
- package/src/rescript/Spice_Codecs.res +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- BREAKING: changes to support rescript v12, will now generate codecs that use Stdlib instead of Js or Belt.
|
|
6
|
+
- Updates codec generation to handle the `result` type in addition to `Belt.Result.t`
|
|
7
|
+
- Polyvariant codecs no longer have an intermediate `Js.Json.tagged` type / function calls.
|
|
8
|
+
|
|
9
|
+
## 0.2.9
|
|
10
|
+
|
|
11
|
+
- Update test project for compiler v12. https://github.com/green-labs/ppx_spice/pull/94
|
|
12
|
+
- Fix bigint codec on rescript v12. https://github.com/green-labs/ppx_spice/pull/93
|
|
13
|
+
|
|
3
14
|
## 0.2.8
|
|
4
15
|
|
|
5
16
|
- Dropped support for curried mode in accordance with compiler v12 changes.
|
|
@@ -33,7 +44,7 @@
|
|
|
33
44
|
## 0.2.1
|
|
34
45
|
|
|
35
46
|
- a190663 Utilize Js.Json.Boolean(bool) instead oif Js.Json.True, False https://github.com/green-labs/ppx_spice/pull/58
|
|
36
|
-
- a190663 Add support of uncurried mode for interface(
|
|
47
|
+
- a190663 Add support of uncurried mode for interface(\*.resi) https://github.com/green-labs/ppx_spice/pull/58
|
|
37
48
|
- Support the compiler v11-rc.5 https://github.com/green-labs/ppx_spice/pull/61
|
|
38
49
|
- Add the feature of encoding/decoding between the number and (polymorphic)variant with `@spice.as` https://github.com/green-labs/ppx_spice/pull/64
|
|
39
50
|
- Fix generating encode, decode function when `@spice.as` with number https://github.com/green-labs/ppx_spice/pull/74
|
package/README.md
CHANGED
|
@@ -128,11 +128,13 @@ Read our [Guide with examples](docs/GUIDE.md)
|
|
|
128
128
|
|
|
129
129
|
### Compatibility on the compiler versions
|
|
130
130
|
|
|
131
|
-
| Compiler
|
|
132
|
-
|
|
|
133
|
-
| v12
|
|
134
|
-
|
|
|
135
|
-
|
|
|
131
|
+
| Compiler | Ppx_spice | Note |
|
|
132
|
+
| ------------- | --------------------- | ----------------------------- |
|
|
133
|
+
| v12-alpha.14 | v0.2.9 >= | Bigint.fromFloat type changed |
|
|
134
|
+
| v12-alpha.5 | v0.2.8 | Curried mode deprecated |
|
|
135
|
+
| v12-alpha.4 | v0.2.7 >= && > v0.2.2 | |
|
|
136
|
+
| v11 | v0.2.2 >= && > v0.2.0 | |
|
|
137
|
+
| v10 | v0.2.0 >= | |
|
|
136
138
|
|
|
137
139
|
NOTE: Starting from v0.2.8, support for curried mode is discontinued to align with the changes in compiler v12.
|
|
138
140
|
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@greenlabs/ppx-spice",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-next.0",
|
|
4
|
+
"packageManager": "yarn@1.22.22",
|
|
4
5
|
"description": "ReScript PPX which generate JSON (de)serializer",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"author": "Greenlabs Dev <developer@greenlabs.co.kr>",
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
"postinstall": "node ./postInstall.js"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
|
-
"@changesets/cli": "^2.26.2"
|
|
23
|
+
"@changesets/cli": "^2.26.2",
|
|
24
|
+
"rescript": "^12.0.0"
|
|
23
25
|
}
|
|
24
|
-
}
|
|
26
|
+
}
|
package/ppx-linux.exe
CHANGED
|
Binary file
|
package/ppx-osx.exe
CHANGED
|
Binary file
|
package/ppx-windows.exe
CHANGED
|
Binary file
|
package/rescript.json
CHANGED
|
@@ -3,20 +3,16 @@
|
|
|
3
3
|
"sources": [
|
|
4
4
|
{
|
|
5
5
|
"dir": "src",
|
|
6
|
-
"subdirs": [
|
|
7
|
-
"rescript"
|
|
8
|
-
]
|
|
6
|
+
"subdirs": ["rescript"]
|
|
9
7
|
},
|
|
10
8
|
{
|
|
11
9
|
"dir": "test",
|
|
12
10
|
"type": "dev"
|
|
13
11
|
}
|
|
14
12
|
],
|
|
15
|
-
"ppx-flags": [
|
|
16
|
-
"./ppx"
|
|
17
|
-
],
|
|
13
|
+
"ppx-flags": ["./ppx"],
|
|
18
14
|
"warnings": {
|
|
19
15
|
"number": "+A-9-40-42"
|
|
20
16
|
},
|
|
21
17
|
"bsc-flags": []
|
|
22
|
-
}
|
|
18
|
+
}
|
package/src/rescript/Spice.res
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
type decodeError = {
|
|
2
2
|
path: string,
|
|
3
3
|
message: string,
|
|
4
|
-
value:
|
|
4
|
+
value: JSON.t,
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
type result<'a> = result<'a, decodeError>
|
|
8
|
-
type decoder<'a> =
|
|
9
|
-
type encoder<'a> = 'a =>
|
|
8
|
+
type decoder<'a> = JSON.t => result<'a>
|
|
9
|
+
type encoder<'a> = 'a => JSON.t
|
|
10
10
|
type codec<'a> = (encoder<'a>, decoder<'a>)
|
|
11
11
|
|
|
12
12
|
let error = (~path=?, message, value) => {
|
|
@@ -17,149 +17,154 @@ let error = (~path=?, message, value) => {
|
|
|
17
17
|
Error({path, message, value})
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
let stringToJson = (s):
|
|
20
|
+
let stringToJson = (s): JSON.t => JSON.String(s)
|
|
21
21
|
let stringFromJson = j =>
|
|
22
|
-
switch (j:
|
|
23
|
-
|
|
|
22
|
+
switch (j: JSON.t) {
|
|
23
|
+
| JSON.String(s) => Ok(s)
|
|
24
24
|
| _ => Error({path: "", message: "Not a string", value: j})
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
let intToJson = (i):
|
|
27
|
+
let intToJson = (i): JSON.t => JSON.Number(Float.fromInt(i))
|
|
28
28
|
let intFromJson = j =>
|
|
29
|
-
switch (j:
|
|
30
|
-
|
|
|
31
|
-
|
|
32
|
-
? Ok(
|
|
29
|
+
switch (j: JSON.t) {
|
|
30
|
+
| JSON.Number(f) =>
|
|
31
|
+
Math.floor(f) == f
|
|
32
|
+
? Ok(Math.Int.floor(f))
|
|
33
33
|
: Error({path: "", message: "Not an integer", value: j})
|
|
34
34
|
|
|
35
35
|
| _ => Error({path: "", message: "Not a number", value: j})
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
let bigintToJson = (i):
|
|
38
|
+
let bigintToJson = (i): JSON.t => JSON.Number(BigInt.toFloat(i))
|
|
39
39
|
|
|
40
40
|
let bigintFromJson = j =>
|
|
41
|
-
switch (j:
|
|
42
|
-
|
|
|
41
|
+
switch (j: JSON.t) {
|
|
42
|
+
| JSON.Number(n) =>
|
|
43
|
+
switch BigInt.fromFloat(n) {
|
|
44
|
+
| Some(v) => v->Ok
|
|
45
|
+
| None => error("Not a bigint", j)
|
|
46
|
+
}
|
|
43
47
|
| _ => error("Not a number", j)
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
let floatToJson = (v):
|
|
50
|
+
let floatToJson = (v): JSON.t => JSON.Number(v)
|
|
47
51
|
let floatFromJson = j =>
|
|
48
|
-
switch (j:
|
|
49
|
-
|
|
|
52
|
+
switch (j: JSON.t) {
|
|
53
|
+
| JSON.Number(f) => Ok(f)
|
|
50
54
|
| _ => Error({path: "", message: "Not a number", value: j})
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
let boolToJson = (v):
|
|
57
|
+
let boolToJson = (v): JSON.t =>
|
|
54
58
|
switch v {
|
|
55
|
-
| true =>
|
|
56
|
-
| false =>
|
|
59
|
+
| true => JSON.Boolean(true)
|
|
60
|
+
| false => JSON.Boolean(false)
|
|
57
61
|
}
|
|
58
62
|
let boolFromJson = j =>
|
|
59
|
-
switch (j:
|
|
60
|
-
|
|
|
61
|
-
|
|
|
63
|
+
switch (j: JSON.t) {
|
|
64
|
+
| JSON.Boolean(true) => Ok(true)
|
|
65
|
+
| JSON.Boolean(false) => Ok(false)
|
|
62
66
|
| _ => Error({path: "", message: "Not a boolean", value: j})
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
let unitToJson = ():
|
|
69
|
+
let unitToJson = (): JSON.t => JSON.Number(0.0)
|
|
66
70
|
let unitFromJson = _ => Ok()
|
|
67
71
|
|
|
68
|
-
let arrayToJson = (encoder, arr):
|
|
72
|
+
let arrayToJson = (encoder, arr): JSON.t => JSON.Array(Array.map(arr, encoder))
|
|
69
73
|
|
|
70
74
|
let arrayFromJson = (decoder, json) =>
|
|
71
|
-
switch (json:
|
|
72
|
-
|
|
|
75
|
+
switch (json: JSON.t) {
|
|
76
|
+
| JSON.Array(arr) =>
|
|
77
|
+
Array.reduceWithIndex(arr, Ok([]), (acc, jsonI, i) =>
|
|
73
78
|
switch (acc, decoder(jsonI)) {
|
|
74
79
|
| (Error(_), _) => acc
|
|
75
80
|
|
|
76
81
|
| (_, Error({path} as error)) =>
|
|
77
82
|
Error({...error, path: "[" ++ (Int.toString(i) ++ ("]" ++ path))})
|
|
78
83
|
|
|
79
|
-
| (Ok(prev), Ok(newVal)) =>
|
|
80
|
-
Ok(Js.Array.concat([newVal], prev))
|
|
84
|
+
| (Ok(prev), Ok(newVal)) => Ok(Array.concat([newVal], prev))
|
|
81
85
|
}
|
|
82
|
-
|
|
86
|
+
)
|
|
83
87
|
|
|
84
88
|
| _ => Error({path: "", message: "Not an array", value: json})
|
|
85
89
|
}
|
|
86
90
|
|
|
87
|
-
let listToJson = (encoder, list) => arrayToJson(encoder,
|
|
91
|
+
let listToJson = (encoder, list) => arrayToJson(encoder, List.toArray(list))
|
|
88
92
|
|
|
89
|
-
let listFromJson = (decoder, json) =>
|
|
90
|
-
Belt.Result.map(arrayFromJson(decoder, json), Belt.List.fromArray)
|
|
93
|
+
let listFromJson = (decoder, json) => Result.map(arrayFromJson(decoder, json), List.fromArray)
|
|
91
94
|
|
|
92
95
|
let filterOptional = arr =>
|
|
93
|
-
|
|
96
|
+
Array.filterMap(arr, ((k, v)) =>
|
|
97
|
+
switch v {
|
|
94
98
|
| Some(v) => Some(k, v)
|
|
95
99
|
| None => None
|
|
96
|
-
|
|
100
|
+
}
|
|
101
|
+
)
|
|
97
102
|
|
|
98
|
-
let optionToJson = (encoder, opt): option<
|
|
103
|
+
let optionToJson = (encoder, opt): option<JSON.t> =>
|
|
99
104
|
switch opt {
|
|
100
105
|
| Some(x) => Some(encoder(x))
|
|
101
106
|
| None => None
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
let optionFromJson = (decoder, json) =>
|
|
105
|
-
switch (json:
|
|
106
|
-
|
|
|
107
|
-
| _ =>
|
|
110
|
+
switch (json: JSON.t) {
|
|
111
|
+
| JSON.Null => Ok(None)
|
|
112
|
+
| _ => Result.map(decoder(json), v => Some(v))
|
|
108
113
|
}
|
|
109
114
|
|
|
110
|
-
let nullToJson = (encoder, opt):
|
|
115
|
+
let nullToJson = (encoder, opt): JSON.t =>
|
|
111
116
|
switch opt {
|
|
112
|
-
|
|
|
113
|
-
| Null =>
|
|
117
|
+
| Null.Value(x) => encoder(x)
|
|
118
|
+
| Null => JSON.Null
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
let nullFromJson = (decoder, json) =>
|
|
117
|
-
switch (json:
|
|
118
|
-
|
|
|
119
|
-
| _ =>
|
|
122
|
+
switch (json: JSON.t) {
|
|
123
|
+
| JSON.Null => Ok(Null.Null)
|
|
124
|
+
| _ => Result.map(decoder(json), v => Null.Value(v))
|
|
120
125
|
}
|
|
121
126
|
|
|
122
|
-
let resultToJson = (okEncoder, errorEncoder, result):
|
|
127
|
+
let resultToJson = (okEncoder, errorEncoder, result): JSON.t => JSON.Array(
|
|
123
128
|
switch result {
|
|
124
|
-
| Ok(v) => [
|
|
125
|
-
| Error(e) => [
|
|
129
|
+
| Ok(v) => [JSON.String("Ok"), okEncoder(v)]
|
|
130
|
+
| Error(e) => [JSON.String("Error"), errorEncoder(e)]
|
|
126
131
|
},
|
|
127
132
|
)
|
|
128
133
|
|
|
129
134
|
let resultFromJson = (okDecoder, errorDecoder, json) =>
|
|
130
|
-
switch (json:
|
|
131
|
-
|
|
|
135
|
+
switch (json: JSON.t) {
|
|
136
|
+
| JSON.Array([variantConstructorId, payload]) =>
|
|
132
137
|
switch variantConstructorId {
|
|
133
|
-
|
|
|
138
|
+
| JSON.String("Ok") => okDecoder(payload)->Result.map(v => Ok(v))
|
|
134
139
|
|
|
135
|
-
|
|
|
140
|
+
| JSON.String("Error") =>
|
|
136
141
|
switch errorDecoder(payload) {
|
|
137
142
|
| Ok(v) => Ok(Error(v))
|
|
138
143
|
| Error(e) => Error(e)
|
|
139
144
|
}
|
|
140
145
|
|
|
141
|
-
|
|
|
146
|
+
| JSON.String(_) => error("Expected either \"Ok\" or \"Error\"", variantConstructorId)
|
|
142
147
|
| _ => error("Not a string", variantConstructorId)
|
|
143
148
|
}
|
|
144
|
-
|
|
|
149
|
+
| JSON.Array(_) => error("Expected exactly 2 values in array", json)
|
|
145
150
|
| _ => error("Not an array", json)
|
|
146
151
|
}
|
|
147
152
|
|
|
148
|
-
let dictToJson = (encoder, dict):
|
|
153
|
+
let dictToJson = (encoder, dict): JSON.t => JSON.Object(Dict.mapValues(dict, encoder))
|
|
149
154
|
|
|
150
155
|
let dictFromJson = (decoder, json) =>
|
|
151
|
-
switch (json:
|
|
152
|
-
|
|
|
156
|
+
switch (json: JSON.t) {
|
|
157
|
+
| JSON.Object(dict) =>
|
|
153
158
|
dict
|
|
154
|
-
->
|
|
155
|
-
->
|
|
159
|
+
->Dict.toArray
|
|
160
|
+
->Array.reduce(Ok(Dict.make()), (acc, (key, value)) =>
|
|
156
161
|
switch (acc, decoder(value)) {
|
|
157
162
|
| (Error(_), _) => acc
|
|
158
163
|
|
|
159
164
|
| (_, Error({path} as error)) => Error({...error, path: "." ++ (key ++ path)})
|
|
160
165
|
|
|
161
166
|
| (Ok(prev), Ok(newVal)) =>
|
|
162
|
-
let () = prev->
|
|
167
|
+
let () = prev->Dict.set(key, newVal)
|
|
163
168
|
Ok(prev)
|
|
164
169
|
}
|
|
165
170
|
)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
let falseableEncode = (encoder, opt) =>
|
|
2
2
|
switch opt {
|
|
3
|
-
| None =>
|
|
3
|
+
| None => JSON.Boolean(false)
|
|
4
4
|
| Some(v) => encoder(v)
|
|
5
5
|
}
|
|
6
6
|
let falseableDecode = (decoder, json) =>
|
|
7
7
|
switch json {
|
|
8
|
-
|
|
|
9
|
-
| _ =>
|
|
8
|
+
| JSON.Boolean(false) => Ok(None)
|
|
9
|
+
| _ => Result.map(decoder(json), v => Some(v))
|
|
10
10
|
}
|
|
11
11
|
let falseable = (falseableEncode, falseableDecode)
|
|
12
12
|
|