@kaiko.io/rescript-deser 4.0.0-rc.4 → 4.0.0-rc.6
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/lib/bs/.bsdeps +4 -4
- package/lib/bs/.compiler.log +2 -2
- package/lib/bs/.ninja_log +18 -26
- package/lib/bs/build.ninja +1 -1
- package/lib/bs/src/JSON.cmi +0 -0
- package/lib/bs/src/JSON.cmt +0 -0
- package/lib/bs/tests/QUnit.cmt +0 -0
- package/lib/bs/tests/index.cmi +0 -0
- package/lib/bs/tests/index.cmt +0 -0
- package/package.json +3 -3
- package/lib/ocaml/.compiler.log +0 -2
- package/lib/ocaml/.ninja_log +0 -7
- package/lib/ocaml/JSON.cmi +0 -0
- package/lib/ocaml/JSON.cmj +0 -0
- package/lib/ocaml/JSON.cmt +0 -0
- package/lib/ocaml/JSON.res +0 -343
- package/lib/ocaml/install.stamp +0 -0
package/lib/bs/.bsdeps
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
11.0.0-rc.
|
|
1
|
+
11.0.0-rc.8
|
|
2
2
|
/home/manu/src/kaiko/rescript-deser
|
|
3
3
|
0
|
|
4
|
-
rescript.json 0x1.
|
|
4
|
+
rescript.json 0x1.95f132e38e01fp+30
|
|
5
5
|
tests 0x1.93fb8b23e3f01p+30
|
|
6
|
-
src/ 0x1.
|
|
6
|
+
src/ 0x1.95f132e38e01fp+30
|
|
7
7
|
===
|
|
8
|
-
/home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/rescript.exe 0x1.
|
|
8
|
+
/home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/rescript.exe 0x1.960678820e55cp+30
|
package/lib/bs/.compiler.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#Start(
|
|
2
|
-
#Done(
|
|
1
|
+
#Start(1702993871083)
|
|
2
|
+
#Done(1702993871083)
|
package/lib/bs/.ninja_log
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
# ninja log v6
|
|
2
|
-
0
|
|
3
|
-
7
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
9
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
10 28 1700765531828957841 src/JSON.cmj 3da9e5f359841f1a
|
|
21
|
-
10 28 1700765531828957841 src/JSON.cmi 3da9e5f359841f1a
|
|
22
|
-
10 28 1700765531828957841 ../es6/src/JSON.js 3da9e5f359841f1a
|
|
23
|
-
10 28 1700765531828957841 ../js/src/JSON.js 3da9e5f359841f1a
|
|
24
|
-
28 38 1700765531838958094 tests/index.cmj 630554c615a94d8d
|
|
25
|
-
28 38 1700765531838958094 tests/index.cmi 630554c615a94d8d
|
|
26
|
-
28 38 1700765531838958094 ../es6/tests/index.js 630554c615a94d8d
|
|
27
|
-
28 38 1700765531838958094 ../js/tests/index.js 630554c615a94d8d
|
|
2
|
+
0 6 1702993853375601095 tests/QUnit.ast 2e0ab126f969eb05
|
|
3
|
+
0 7 1702993853375601095 tests/index.ast 71b3927cad444e4e
|
|
4
|
+
0 8 1702993853378934529 src/JSON.ast 9351863d7438f8a8
|
|
5
|
+
6 8 1702993853378934529 tests/QUnit.d 4a2631c992d93ce7
|
|
6
|
+
7 9 1702993853378934529 tests/index.d 5a4db9cdecd186b3
|
|
7
|
+
8 10 1702993853378934529 src/JSON.d cd2d6773c781340f
|
|
8
|
+
8 15 1702993853385601399 tests/QUnit.cmj 1edb54518110233d
|
|
9
|
+
8 15 1702993853385601399 tests/QUnit.cmi 1edb54518110233d
|
|
10
|
+
8 15 1702993853385601399 ../es6/tests/QUnit.js 1edb54518110233d
|
|
11
|
+
8 15 1702993853385601399 ../js/tests/QUnit.js 1edb54518110233d
|
|
12
|
+
10 28 1702993853398935137 src/JSON.cmj 8c11ebba20f6863e
|
|
13
|
+
10 28 1702993853398935137 src/JSON.cmi 8c11ebba20f6863e
|
|
14
|
+
10 28 1702993853398935137 ../es6/src/JSON.js 8c11ebba20f6863e
|
|
15
|
+
10 28 1702993853398935137 ../js/src/JSON.js 8c11ebba20f6863e
|
|
16
|
+
28 38 1702993853408935441 tests/index.cmj ef71549c32d73e54
|
|
17
|
+
28 38 1702993853408935441 tests/index.cmi ef71549c32d73e54
|
|
18
|
+
28 38 1702993853408935441 ../es6/tests/index.js ef71549c32d73e54
|
|
19
|
+
28 38 1702993853408935441 ../js/tests/index.js ef71549c32d73e54
|
package/lib/bs/build.ninja
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
rescript = 1
|
|
2
2
|
g_finger := /home/manu/src/kaiko/rescript-deser/node_modules/@kaiko.io/rescript-prelude/lib/ocaml/install.stamp
|
|
3
3
|
rule astj
|
|
4
|
-
command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsc.exe -warn-error +8+11+26+27+33+56 -bs-v 11.0.0-rc.
|
|
4
|
+
command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsc.exe -warn-error +8+11+26+27+33+56 -bs-v 11.0.0-rc.8 -uncurried -absname -bs-ast -o $out $i
|
|
5
5
|
o tests/index.ast : astj ../../tests/index.res
|
|
6
6
|
rule deps_dev
|
|
7
7
|
command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsb_helper.exe -g -hash 84aecc33f8594375b23a1a137b057f93 $in
|
package/lib/bs/src/JSON.cmi
CHANGED
|
Binary file
|
package/lib/bs/src/JSON.cmt
CHANGED
|
Binary file
|
package/lib/bs/tests/QUnit.cmt
CHANGED
|
Binary file
|
package/lib/bs/tests/index.cmi
CHANGED
|
Binary file
|
package/lib/bs/tests/index.cmt
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaiko.io/rescript-deser",
|
|
3
|
-
"version": "4.0.0-rc.
|
|
3
|
+
"version": "4.0.0-rc.6",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"json",
|
|
6
6
|
"deserializer",
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
"README.md"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@kaiko.io/rescript-prelude": "7.0.0-rc.
|
|
23
|
+
"@kaiko.io/rescript-prelude": "7.0.0-rc.7"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"esbuild": "^0.15.7",
|
|
27
27
|
"qunit": "^2.16.0",
|
|
28
|
-
"rescript": "11.0.0-rc.
|
|
28
|
+
"rescript": "11.0.0-rc.8"
|
|
29
29
|
}
|
|
30
30
|
}
|
package/lib/ocaml/.compiler.log
DELETED
package/lib/ocaml/.ninja_log
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# ninja log v6
|
|
2
|
-
0 3 1700763106533253326 JSON.cmi bafb789a597a23fb
|
|
3
|
-
0 3 1700763106533253326 JSON.cmj e0df0c7e15c09f8e
|
|
4
|
-
0 3 1700763106533253326 JSON.cmt cb51be205f02087e
|
|
5
|
-
1 3 1700763106533253326 JSON.res b4c17270ea3dc72d
|
|
6
|
-
3 4 1700763106536586783 install.stamp cff5a5b4c02d30cf
|
|
7
|
-
0 2 1700763494803628812 JSON.cmt cb51be205f02087e
|
package/lib/ocaml/JSON.cmi
DELETED
|
Binary file
|
package/lib/ocaml/JSON.cmj
DELETED
|
Binary file
|
package/lib/ocaml/JSON.cmt
DELETED
|
Binary file
|
package/lib/ocaml/JSON.res
DELETED
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
@@uncurried
|
|
2
|
-
open Prelude
|
|
3
|
-
|
|
4
|
-
module FieldValue = {
|
|
5
|
-
type t
|
|
6
|
-
external string: string => t = "%identity"
|
|
7
|
-
external int: int => t = "%identity"
|
|
8
|
-
external float: float => t = "%identity"
|
|
9
|
-
external boolean: bool => t = "%identity"
|
|
10
|
-
external array: array<t> => t = "%identity"
|
|
11
|
-
external object: Dict.t<t> => t = "%identity"
|
|
12
|
-
external mapping: Dict.t<t> => t = "%identity"
|
|
13
|
-
external any: 'a => t = "%identity"
|
|
14
|
-
@val external null: t = "undefined"
|
|
15
|
-
|
|
16
|
-
external asString: t => string = "%identity"
|
|
17
|
-
external asInt: t => int = "%identity"
|
|
18
|
-
external asFloat: t => float = "%identity"
|
|
19
|
-
external asBoolean: t => bool = "%identity"
|
|
20
|
-
external asArray: t => array<'a> = "%identity"
|
|
21
|
-
external asObject: t => 'a = "%identity"
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
exception TypeError(string)
|
|
25
|
-
|
|
26
|
-
@doc("The module type of a built deserializer which is suitable to add as a subparser.")
|
|
27
|
-
module type Deserializer = {
|
|
28
|
-
type t
|
|
29
|
-
let name: string
|
|
30
|
-
let fromJSON: Js.Json.t => result<t, string>
|
|
31
|
-
let checkFieldsSanity: unit => result<unit, string>
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
module Field = {
|
|
35
|
-
type rec t =
|
|
36
|
-
| Any
|
|
37
|
-
| String
|
|
38
|
-
| Literal(string)
|
|
39
|
-
| Int
|
|
40
|
-
| Float
|
|
41
|
-
| Boolean
|
|
42
|
-
| Array(t)
|
|
43
|
-
/// These SHOULD strings in ISO format, but we only validate the string
|
|
44
|
-
/// can be represented in Js.Date without spewing NaN all over the place;
|
|
45
|
-
/// Js.Date.fromString("xxx") returns an object that is mostly unusable.
|
|
46
|
-
///
|
|
47
|
-
/// We also allow floats and then use Js.Date.fromFloat.
|
|
48
|
-
| Date
|
|
49
|
-
| Datetime // alias of Date
|
|
50
|
-
|
|
51
|
-
| Tuple(array<t>)
|
|
52
|
-
| Object(array<(string, t)>)
|
|
53
|
-
| Optional(t)
|
|
54
|
-
| OptionalWithDefault(t, FieldValue.t)
|
|
55
|
-
/// An arbitrary mapping from names to other arbitrary fields. The
|
|
56
|
-
/// difference with Object, is that you don't know the names of the
|
|
57
|
-
/// expected entries.
|
|
58
|
-
| Mapping(t)
|
|
59
|
-
|
|
60
|
-
| Deserializer(module(Deserializer))
|
|
61
|
-
|
|
62
|
-
/// A specialized Array of deserialized items that ignores unparsable
|
|
63
|
-
/// items and returns the valid collection. This saves the user from
|
|
64
|
-
/// writing 'Array(DefaultWhenInvalid(Optional(Deserializer(module(M)))))'
|
|
65
|
-
/// and then post-process the list of items with 'Array.keepSome'
|
|
66
|
-
| Collection(module(Deserializer))
|
|
67
|
-
| DefaultWhenInvalid(t, FieldValue.t)
|
|
68
|
-
|
|
69
|
-
// FIXME: this is used to add additional restrictions like variadictInt or
|
|
70
|
-
// variadicString; but I find it too type-unsafe. I might consider having
|
|
71
|
-
// a Constraints for this in the future.
|
|
72
|
-
| Morphism(t, FieldValue.t => FieldValue.t)
|
|
73
|
-
|
|
74
|
-
| Self
|
|
75
|
-
|
|
76
|
-
let usingString = (f: string => 'a) => value => value->FieldValue.asString->f->FieldValue.any
|
|
77
|
-
let usingInt = (f: int => 'a) => value => value->FieldValue.asInt->f->FieldValue.any
|
|
78
|
-
let usingFloat = (f: float => 'a) => value => value->FieldValue.asFloat->f->FieldValue.any
|
|
79
|
-
let usingBoolean = (f: bool => 'a) => value => value->FieldValue.asBoolean->f->FieldValue.any
|
|
80
|
-
let usingArray = (f: array<'a> => 'b) => value => value->FieldValue.asArray->f->FieldValue.any
|
|
81
|
-
let usingObject = (f: 'a => 'b) => value => value->FieldValue.asObject->f->FieldValue.any
|
|
82
|
-
|
|
83
|
-
let variadicInt = (hint: string, fromJs: int => option<'variadicType>) => Morphism(
|
|
84
|
-
Int,
|
|
85
|
-
usingInt(i => {
|
|
86
|
-
switch i->fromJs {
|
|
87
|
-
| Some(internalValue) => internalValue
|
|
88
|
-
| None =>
|
|
89
|
-
raise(TypeError(`This Int(${i->Int.toString}) not a valid value here. Hint: ${hint}`))
|
|
90
|
-
}
|
|
91
|
-
}),
|
|
92
|
-
)
|
|
93
|
-
let variadicString = (hint: string, fromJs: string => option<'variadicType>) => Morphism(
|
|
94
|
-
String,
|
|
95
|
-
usingString(i => {
|
|
96
|
-
switch i->fromJs {
|
|
97
|
-
| Some(internalValue) => internalValue
|
|
98
|
-
| None => raise(TypeError(`This String("${i}") not a valid value here. Hint: ${hint}`))
|
|
99
|
-
}
|
|
100
|
-
}),
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
let rec toString = (type_: t) =>
|
|
104
|
-
switch type_ {
|
|
105
|
-
| Any => "Any"
|
|
106
|
-
| String => "String"
|
|
107
|
-
| Literal(lit) => `Literal: ${lit}`
|
|
108
|
-
| Int => "Integer"
|
|
109
|
-
| Float => "Float"
|
|
110
|
-
| Boolean => "Boolean"
|
|
111
|
-
| Datetime
|
|
112
|
-
| Date => "Date"
|
|
113
|
-
| Self => "Self (recursive)"
|
|
114
|
-
| Collection(m) => {
|
|
115
|
-
module M = unpack(m: Deserializer)
|
|
116
|
-
"Collection of " ++ M.name
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
| Array(t) => "Array of " ++ t->toString
|
|
120
|
-
| Tuple(bases) => `Tuple of (${bases->Array.map(toString)->Array.join(", ")})`
|
|
121
|
-
| Object(fields) => {
|
|
122
|
-
let desc = fields->Array.map(((field, t)) => `${field}: ${t->toString}`)->Array.join(", ")
|
|
123
|
-
`Object of {${desc}}`
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
| OptionalWithDefault(t, _)
|
|
127
|
-
| Optional(t) =>
|
|
128
|
-
"Null of " ++ t->toString
|
|
129
|
-
| Mapping(t) => `Mapping of ${t->toString}`
|
|
130
|
-
| Morphism(t, _) => t->toString ++ " to apply a morphism"
|
|
131
|
-
| Deserializer(m) => {
|
|
132
|
-
module M = unpack(m: Deserializer)
|
|
133
|
-
M.name
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
| DefaultWhenInvalid(t, _) => `Protected ${t->toString}`
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
let _taggedToString = (tagged: Js.Json.tagged_t) => {
|
|
140
|
-
switch tagged {
|
|
141
|
-
| Js.Json.JSONFalse => "Boolean(false)"
|
|
142
|
-
| Js.Json.JSONTrue => "Boolean(true)"
|
|
143
|
-
| Js.Json.JSONNull => "Null"
|
|
144
|
-
| Js.Json.JSONString(text) => `String("${text}")`
|
|
145
|
-
| Js.Json.JSONNumber(number) => `Number(${number->Float.toString})`
|
|
146
|
-
| Js.Json.JSONObject(obj) => `Object(${obj->Js.Json.stringifyAny->default("...")})`
|
|
147
|
-
| Js.Json.JSONArray(array) => `Array(${array->Js.Json.stringifyAny->default("...")})`
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
let rec extractValue = (
|
|
152
|
-
values: Dict.t<Js.Json.t>,
|
|
153
|
-
field: string,
|
|
154
|
-
shape: t,
|
|
155
|
-
self: t,
|
|
156
|
-
): FieldValue.t => {
|
|
157
|
-
switch values->Dict.get(field) {
|
|
158
|
-
| Some(value) => value->fromUntagged(shape, self)
|
|
159
|
-
| None =>
|
|
160
|
-
switch shape {
|
|
161
|
-
| DefaultWhenInvalid(_, _) => Js.Json.null->fromUntagged(shape, self)
|
|
162
|
-
| Optional(_) => Js.Json.null->fromUntagged(shape, self)
|
|
163
|
-
| OptionalWithDefault(_, default) => default
|
|
164
|
-
| _ => raise(TypeError(`Missing non-optional field '${field}'`))
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
and fromUntagged = (untagged: Js.Json.t, shape: t, self: t): FieldValue.t => {
|
|
169
|
-
switch (shape, untagged->Js.Json.classify) {
|
|
170
|
-
| (Any, _) => untagged->FieldValue.any
|
|
171
|
-
| (Literal(expected), Js.Json.JSONString(text)) =>
|
|
172
|
-
if text == expected {
|
|
173
|
-
FieldValue.string(text)
|
|
174
|
-
} else {
|
|
175
|
-
raise(TypeError(`Expecting literal ${expected}, got ${text}`))
|
|
176
|
-
}
|
|
177
|
-
| (String, Js.Json.JSONString(text)) => FieldValue.string(text)
|
|
178
|
-
| (Int, Js.Json.JSONNumber(number)) => FieldValue.int(number->Float.toInt)
|
|
179
|
-
| (Float, Js.Json.JSONNumber(number)) => FieldValue.float(number)
|
|
180
|
-
| (Boolean, Js.Json.JSONTrue) => FieldValue.boolean(true)
|
|
181
|
-
| (Boolean, Js.Json.JSONFalse) => FieldValue.boolean(false)
|
|
182
|
-
| (Tuple(bases), Js.Json.JSONArray(items)) => {
|
|
183
|
-
let lenbases = bases->Array.length
|
|
184
|
-
let lenitems = items->Array.length
|
|
185
|
-
if lenbases == lenitems {
|
|
186
|
-
let values = Array.zipBy(items, bases, (i, b) => fromUntagged(i, b, self))
|
|
187
|
-
values->FieldValue.array
|
|
188
|
-
} else {
|
|
189
|
-
raise(
|
|
190
|
-
TypeError(`Expecting ${lenbases->Int.toString} items, got ${lenitems->Int.toString}`),
|
|
191
|
-
)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
| (Datetime, Js.Json.JSONString(s))
|
|
196
|
-
| (Date, Js.Json.JSONString(s)) => {
|
|
197
|
-
let r = Js.Date.fromString(s)
|
|
198
|
-
if r->Js.Date.getDate->Js.Float.isNaN {
|
|
199
|
-
raise(TypeError(`Invalid date ${s}`))
|
|
200
|
-
}
|
|
201
|
-
r->FieldValue.any
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
| (Datetime, Js.Json.JSONNumber(f))
|
|
205
|
-
| (Date, Js.Json.JSONNumber(f)) => {
|
|
206
|
-
let r = Js.Date.fromFloat(f)
|
|
207
|
-
if r->Js.Date.getDate->Js.Float.isNaN {
|
|
208
|
-
raise(TypeError(`Invalid date ${f->Js.Float.toString}`))
|
|
209
|
-
}
|
|
210
|
-
r->FieldValue.any
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
| (Array(shape), Js.Json.JSONArray(items)) =>
|
|
214
|
-
FieldValue.array(items->Array.map(item => item->fromUntagged(shape, self)))
|
|
215
|
-
| (Mapping(f), Js.Json.JSONObject(values)) =>
|
|
216
|
-
values->Dict.mapValues(v => v->fromUntagged(f, self))->FieldValue.mapping
|
|
217
|
-
| (Object(fields), Js.Json.JSONObject(values)) =>
|
|
218
|
-
FieldValue.object(
|
|
219
|
-
fields
|
|
220
|
-
->Array.map(((field, shape)) => {
|
|
221
|
-
let value = switch extractValue(values, field, shape, self) {
|
|
222
|
-
| value => value
|
|
223
|
-
| exception TypeError(msg) => raise(TypeError(`Field "${field}": ${msg}`))
|
|
224
|
-
}
|
|
225
|
-
(field, value)
|
|
226
|
-
})
|
|
227
|
-
->Dict.fromArray,
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
| (OptionalWithDefault(_, value), Js.Json.JSONNull) => value
|
|
231
|
-
| (OptionalWithDefault(shape, _), _) => untagged->fromUntagged(shape, self)
|
|
232
|
-
| (Optional(_), Js.Json.JSONNull) => FieldValue.null
|
|
233
|
-
| (Optional(shape), _) => untagged->fromUntagged(shape, self)
|
|
234
|
-
| (Morphism(shape, f), _) => untagged->fromUntagged(shape, self)->f->FieldValue.any
|
|
235
|
-
|
|
236
|
-
| (Collection(m), Js.Json.JSONArray(items)) => {
|
|
237
|
-
module M = unpack(m: Deserializer)
|
|
238
|
-
items
|
|
239
|
-
->Array.map(M.fromJSON)
|
|
240
|
-
->Array.map(Result.warn)
|
|
241
|
-
->Array.keepSome
|
|
242
|
-
->Array.map(FieldValue.any)
|
|
243
|
-
->FieldValue.array
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
| (Deserializer(m), _) => {
|
|
247
|
-
module M = unpack(m: Deserializer)
|
|
248
|
-
switch untagged->M.fromJSON {
|
|
249
|
-
| Ok(res) => res->FieldValue.any
|
|
250
|
-
| Error(msg) => raise(TypeError(msg))
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
| (DefaultWhenInvalid(t, default), _) =>
|
|
255
|
-
switch untagged->fromUntagged(t, self) {
|
|
256
|
-
| res => res
|
|
257
|
-
| exception TypeError(msg) => {
|
|
258
|
-
Js.Console.warn2("Detected and ignore (with default): ", msg)
|
|
259
|
-
default
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
| (Self, _) => untagged->fromUntagged(self, self)
|
|
263
|
-
| (expected, actual) =>
|
|
264
|
-
raise(TypeError(`Expected ${expected->toString}, but got ${actual->_taggedToString} instead`))
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
let rec checkFieldsSanity = (name: string, fields: t, optional: bool): result<unit, string> =>
|
|
269
|
-
switch (fields, optional) {
|
|
270
|
-
| (Self, false) => Error(`${name}: Trivial infinite recursion 'let fields = Self'`)
|
|
271
|
-
| (Self, true) => Ok()
|
|
272
|
-
|
|
273
|
-
| (Any, _) => Ok()
|
|
274
|
-
| (String, _) | (Float, _) | (Int, _) | (Literal(_), _) => Ok()
|
|
275
|
-
| (Boolean, _) | (Date, _) | (Datetime, _) => Ok()
|
|
276
|
-
| (Morphism(_, _), _) => Ok()
|
|
277
|
-
|
|
278
|
-
| (Collection(mod), _)
|
|
279
|
-
| (Deserializer(mod), _) => {
|
|
280
|
-
module M = unpack(mod: Deserializer)
|
|
281
|
-
switch M.checkFieldsSanity() {
|
|
282
|
-
| Ok() => Ok()
|
|
283
|
-
| Error(msg) => Error(`${name}/ ${msg}`)
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
| (DefaultWhenInvalid(fields, _), _)
|
|
288
|
-
| (OptionalWithDefault(fields, _), _)
|
|
289
|
-
| (Optional(fields), _) =>
|
|
290
|
-
checkFieldsSanity(name, fields, true)
|
|
291
|
-
|
|
292
|
-
| (Object(fields), optional) =>
|
|
293
|
-
fields
|
|
294
|
-
->Array.map(((fieldName, field)) => () =>
|
|
295
|
-
checkFieldsSanity(`${name}::${fieldName}`, field, optional))
|
|
296
|
-
->ManyResults.bailU
|
|
297
|
-
->ManyResults.map(_ => ())
|
|
298
|
-
|
|
299
|
-
/// Mappings and arrays can be empty, so their payloads are
|
|
300
|
-
/// automatically optional.
|
|
301
|
-
| (Mapping(field), _) | (Array(field), _) => checkFieldsSanity(name, field, true)
|
|
302
|
-
|
|
303
|
-
| (Tuple(fields), optional) =>
|
|
304
|
-
fields
|
|
305
|
-
->Array.mapWithIndex((field, index) => () =>
|
|
306
|
-
checkFieldsSanity(`${name}[${index->Int.toString}]`, field, optional))
|
|
307
|
-
->ManyResults.bailU
|
|
308
|
-
->ManyResults.map(_ => ())
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
module type Serializable = {
|
|
313
|
-
type t
|
|
314
|
-
let fields: Field.t
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
module MakeDeserializer = (S: Serializable): (Deserializer with type t = S.t) => {
|
|
318
|
-
type t = S.t
|
|
319
|
-
let fields = S.fields
|
|
320
|
-
%%private(let (loc, _f) = __LOC_OF__(module(S: Serializable)))
|
|
321
|
-
let name = `Deserializer ${__MODULE__}, ${loc}`
|
|
322
|
-
|
|
323
|
-
%%private(external _toNativeType: FieldValue.t => t = "%identity")
|
|
324
|
-
|
|
325
|
-
@doc("Checks for trivial infinite-recursion in the fields of the module.
|
|
326
|
-
|
|
327
|
-
Notice this algorithm is just an heuristic, and it might happen that are
|
|
328
|
-
cases of infinite-recursion not detected and cases where detection is a
|
|
329
|
-
false positive.
|
|
330
|
-
|
|
331
|
-
You should use this only while debugging/developing to verify your data.
|
|
332
|
-
|
|
333
|
-
")
|
|
334
|
-
let checkFieldsSanity = () => Field.checkFieldsSanity(name, fields, false)
|
|
335
|
-
|
|
336
|
-
@doc("Parse a `Js.Json.t` into `result<t, string>`")
|
|
337
|
-
let fromJSON = (json: Js.Json.t): result<t, _> => {
|
|
338
|
-
switch json->Field.fromUntagged(fields, fields) {
|
|
339
|
-
| res => Ok(res->_toNativeType)
|
|
340
|
-
| exception TypeError(e) => Error(e)
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
package/lib/ocaml/install.stamp
DELETED
|
File without changes
|