@greenlabs/ppx-spice 0.2.9 → 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 +7 -1
- 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 +61 -60
- package/src/rescript/Spice_Codecs.res +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
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
|
+
|
|
3
9
|
## 0.2.9
|
|
4
10
|
|
|
5
11
|
- Update test project for compiler v12. https://github.com/green-labs/ppx_spice/pull/94
|
|
@@ -38,7 +44,7 @@
|
|
|
38
44
|
## 0.2.1
|
|
39
45
|
|
|
40
46
|
- a190663 Utilize Js.Json.Boolean(bool) instead oif Js.Json.True, False https://github.com/green-labs/ppx_spice/pull/58
|
|
41
|
-
- 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
|
|
42
48
|
- Support the compiler v11-rc.5 https://github.com/green-labs/ppx_spice/pull/61
|
|
43
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
|
|
44
50
|
- Fix generating encode, decode function when `@spice.as` with number https://github.com/green-labs/ppx_spice/pull/74
|
|
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,29 +17,29 @@ 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
43
|
switch BigInt.fromFloat(n) {
|
|
44
44
|
| Some(v) => v->Ok
|
|
45
45
|
| None => error("Not a bigint", j)
|
|
@@ -47,123 +47,124 @@ let bigintFromJson = j =>
|
|
|
47
47
|
| _ => error("Not a number", j)
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
let floatToJson = (v):
|
|
50
|
+
let floatToJson = (v): JSON.t => JSON.Number(v)
|
|
51
51
|
let floatFromJson = j =>
|
|
52
|
-
switch (j:
|
|
53
|
-
|
|
|
52
|
+
switch (j: JSON.t) {
|
|
53
|
+
| JSON.Number(f) => Ok(f)
|
|
54
54
|
| _ => Error({path: "", message: "Not a number", value: j})
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
let boolToJson = (v):
|
|
57
|
+
let boolToJson = (v): JSON.t =>
|
|
58
58
|
switch v {
|
|
59
|
-
| true =>
|
|
60
|
-
| false =>
|
|
59
|
+
| true => JSON.Boolean(true)
|
|
60
|
+
| false => JSON.Boolean(false)
|
|
61
61
|
}
|
|
62
62
|
let boolFromJson = j =>
|
|
63
|
-
switch (j:
|
|
64
|
-
|
|
|
65
|
-
|
|
|
63
|
+
switch (j: JSON.t) {
|
|
64
|
+
| JSON.Boolean(true) => Ok(true)
|
|
65
|
+
| JSON.Boolean(false) => Ok(false)
|
|
66
66
|
| _ => Error({path: "", message: "Not a boolean", value: j})
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
let unitToJson = ():
|
|
69
|
+
let unitToJson = (): JSON.t => JSON.Number(0.0)
|
|
70
70
|
let unitFromJson = _ => Ok()
|
|
71
71
|
|
|
72
|
-
let arrayToJson = (encoder, arr):
|
|
72
|
+
let arrayToJson = (encoder, arr): JSON.t => JSON.Array(Array.map(arr, encoder))
|
|
73
73
|
|
|
74
74
|
let arrayFromJson = (decoder, json) =>
|
|
75
|
-
switch (json:
|
|
76
|
-
|
|
|
75
|
+
switch (json: JSON.t) {
|
|
76
|
+
| JSON.Array(arr) =>
|
|
77
|
+
Array.reduceWithIndex(arr, Ok([]), (acc, jsonI, i) =>
|
|
77
78
|
switch (acc, decoder(jsonI)) {
|
|
78
79
|
| (Error(_), _) => acc
|
|
79
80
|
|
|
80
81
|
| (_, Error({path} as error)) =>
|
|
81
82
|
Error({...error, path: "[" ++ (Int.toString(i) ++ ("]" ++ path))})
|
|
82
83
|
|
|
83
|
-
| (Ok(prev), Ok(newVal)) =>
|
|
84
|
-
Ok(Js.Array.concat([newVal], prev))
|
|
84
|
+
| (Ok(prev), Ok(newVal)) => Ok(Array.concat([newVal], prev))
|
|
85
85
|
}
|
|
86
|
-
|
|
86
|
+
)
|
|
87
87
|
|
|
88
88
|
| _ => Error({path: "", message: "Not an array", value: json})
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
let listToJson = (encoder, list) => arrayToJson(encoder,
|
|
91
|
+
let listToJson = (encoder, list) => arrayToJson(encoder, List.toArray(list))
|
|
92
92
|
|
|
93
|
-
let listFromJson = (decoder, json) =>
|
|
94
|
-
Belt.Result.map(arrayFromJson(decoder, json), Belt.List.fromArray)
|
|
93
|
+
let listFromJson = (decoder, json) => Result.map(arrayFromJson(decoder, json), List.fromArray)
|
|
95
94
|
|
|
96
95
|
let filterOptional = arr =>
|
|
97
|
-
|
|
96
|
+
Array.filterMap(arr, ((k, v)) =>
|
|
97
|
+
switch v {
|
|
98
98
|
| Some(v) => Some(k, v)
|
|
99
99
|
| None => None
|
|
100
|
-
|
|
100
|
+
}
|
|
101
|
+
)
|
|
101
102
|
|
|
102
|
-
let optionToJson = (encoder, opt): option<
|
|
103
|
+
let optionToJson = (encoder, opt): option<JSON.t> =>
|
|
103
104
|
switch opt {
|
|
104
105
|
| Some(x) => Some(encoder(x))
|
|
105
106
|
| None => None
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
let optionFromJson = (decoder, json) =>
|
|
109
|
-
switch (json:
|
|
110
|
-
|
|
|
111
|
-
| _ =>
|
|
110
|
+
switch (json: JSON.t) {
|
|
111
|
+
| JSON.Null => Ok(None)
|
|
112
|
+
| _ => Result.map(decoder(json), v => Some(v))
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
let nullToJson = (encoder, opt):
|
|
115
|
+
let nullToJson = (encoder, opt): JSON.t =>
|
|
115
116
|
switch opt {
|
|
116
|
-
|
|
|
117
|
-
| Null =>
|
|
117
|
+
| Null.Value(x) => encoder(x)
|
|
118
|
+
| Null => JSON.Null
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
let nullFromJson = (decoder, json) =>
|
|
121
|
-
switch (json:
|
|
122
|
-
|
|
|
123
|
-
| _ =>
|
|
122
|
+
switch (json: JSON.t) {
|
|
123
|
+
| JSON.Null => Ok(Null.Null)
|
|
124
|
+
| _ => Result.map(decoder(json), v => Null.Value(v))
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
let resultToJson = (okEncoder, errorEncoder, result):
|
|
127
|
+
let resultToJson = (okEncoder, errorEncoder, result): JSON.t => JSON.Array(
|
|
127
128
|
switch result {
|
|
128
|
-
| Ok(v) => [
|
|
129
|
-
| Error(e) => [
|
|
129
|
+
| Ok(v) => [JSON.String("Ok"), okEncoder(v)]
|
|
130
|
+
| Error(e) => [JSON.String("Error"), errorEncoder(e)]
|
|
130
131
|
},
|
|
131
132
|
)
|
|
132
133
|
|
|
133
134
|
let resultFromJson = (okDecoder, errorDecoder, json) =>
|
|
134
|
-
switch (json:
|
|
135
|
-
|
|
|
135
|
+
switch (json: JSON.t) {
|
|
136
|
+
| JSON.Array([variantConstructorId, payload]) =>
|
|
136
137
|
switch variantConstructorId {
|
|
137
|
-
|
|
|
138
|
+
| JSON.String("Ok") => okDecoder(payload)->Result.map(v => Ok(v))
|
|
138
139
|
|
|
139
|
-
|
|
|
140
|
+
| JSON.String("Error") =>
|
|
140
141
|
switch errorDecoder(payload) {
|
|
141
142
|
| Ok(v) => Ok(Error(v))
|
|
142
143
|
| Error(e) => Error(e)
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
|
|
|
146
|
+
| JSON.String(_) => error("Expected either \"Ok\" or \"Error\"", variantConstructorId)
|
|
146
147
|
| _ => error("Not a string", variantConstructorId)
|
|
147
148
|
}
|
|
148
|
-
|
|
|
149
|
+
| JSON.Array(_) => error("Expected exactly 2 values in array", json)
|
|
149
150
|
| _ => error("Not an array", json)
|
|
150
151
|
}
|
|
151
152
|
|
|
152
|
-
let dictToJson = (encoder, dict):
|
|
153
|
+
let dictToJson = (encoder, dict): JSON.t => JSON.Object(Dict.mapValues(dict, encoder))
|
|
153
154
|
|
|
154
155
|
let dictFromJson = (decoder, json) =>
|
|
155
|
-
switch (json:
|
|
156
|
-
|
|
|
156
|
+
switch (json: JSON.t) {
|
|
157
|
+
| JSON.Object(dict) =>
|
|
157
158
|
dict
|
|
158
|
-
->
|
|
159
|
-
->
|
|
159
|
+
->Dict.toArray
|
|
160
|
+
->Array.reduce(Ok(Dict.make()), (acc, (key, value)) =>
|
|
160
161
|
switch (acc, decoder(value)) {
|
|
161
162
|
| (Error(_), _) => acc
|
|
162
163
|
|
|
163
164
|
| (_, Error({path} as error)) => Error({...error, path: "." ++ (key ++ path)})
|
|
164
165
|
|
|
165
166
|
| (Ok(prev), Ok(newVal)) =>
|
|
166
|
-
let () = prev->
|
|
167
|
+
let () = prev->Dict.set(key, newVal)
|
|
167
168
|
Ok(prev)
|
|
168
169
|
}
|
|
169
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
|
|