@kaiko.io/rescript-deser 4.0.0-rc.2 → 4.0.0-rc.3

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/.bsbuild CHANGED
Binary file
package/lib/bs/.bsdeps CHANGED
@@ -1,8 +1,7 @@
1
1
  11.0.0-rc.6
2
- /home/manu/src/kaiko/rescript-deser
3
- 0
2
+ /home/manu/src/merchise/web/photocuba/src/frontend/node_modules/@kaiko.io/rescript-deser
3
+ 1 -bs-package-output es6:lib/es6:.js4Automatic
4
4
  rescript.json 0x1.94b3a6a1d2ba4p+30
5
- tests 0x1.93fb8b23e3f01p+30
6
- src/ 0x1.94b3a6a1d2ba4p+30
5
+ src/ 0x1.957e56214e505p+30
7
6
  ===
8
- /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/rescript.exe 0x1.9578a22fcfdf4p+30
7
+ /home/manu/src/merchise/web/photocuba/src/frontend/node_modules/rescript/linux/rescript.exe 0x1.9578a22fcfdf4p+30
@@ -1,2 +1,2 @@
1
- #Start(1700670041426)
2
- #Done(1700670041426)
1
+ #Start(1700763106505)
2
+ #Done(1700763106531)
package/lib/bs/.ninja_log CHANGED
@@ -1,19 +1,6 @@
1
1
  # ninja log v6
2
- 0 6 1700670039254870652 tests/QUnit.ast a6a94a20e20f8557
3
- 1 7 1700670039254870652 tests/index.ast 3c91d8240b8bb4b8
4
- 1 8 1700670039254870652 src/JSON.ast 54dacc9e71f78ec4
5
- 6 9 1700670039254870652 tests/QUnit.d 4a2631c992d93ce7
6
- 7 9 1700670039254870652 tests/index.d 5a4db9cdecd186b3
7
- 8 10 1700670039258204077 src/JSON.d cd2d6773c781340f
8
- 9 15 1700670039261537502 tests/QUnit.cmj 1baf089a71e93e14
9
- 9 15 1700670039261537502 tests/QUnit.cmi 1baf089a71e93e14
10
- 9 15 1700670039261537502 ../es6/tests/QUnit.js 1baf089a71e93e14
11
- 9 15 1700670039261537502 ../js/tests/QUnit.js 1baf089a71e93e14
12
- 10 28 1700670039274871200 src/JSON.cmj 5c6bd34c8b98f8b9
13
- 10 28 1700670039274871200 src/JSON.cmi 5c6bd34c8b98f8b9
14
- 10 28 1700670039274871200 ../es6/src/JSON.js 5c6bd34c8b98f8b9
15
- 10 28 1700670039274871200 ../js/src/JSON.js 5c6bd34c8b98f8b9
16
- 28 38 1700670039284871474 tests/index.cmj 8a0bf0b0432467b0
17
- 28 38 1700670039284871474 tests/index.cmi 8a0bf0b0432467b0
18
- 28 38 1700670039284871474 ../es6/tests/index.js 8a0bf0b0432467b0
19
- 28 38 1700670039284871474 ../js/tests/index.js 8a0bf0b0432467b0
2
+ 0 7 1700763106509919117 src/JSON.ast 3df97f11bfe4e9b4
3
+ 7 9 1700763106513252576 src/JSON.d 54f2190af6eab30f
4
+ 9 26 1700763106529919867 src/JSON.cmj f5326fd4af8f39e2
5
+ 9 26 1700763106529919867 src/JSON.cmi f5326fd4af8f39e2
6
+ 9 26 1700763106529919867 ../es6/src/JSON.js f5326fd4af8f39e2
@@ -1,27 +1,14 @@
1
1
  rescript = 1
2
- g_finger := /home/manu/src/kaiko/rescript-deser/node_modules/@kaiko.io/rescript-prelude/lib/ocaml/install.stamp
2
+ g_finger := /home/manu/src/merchise/web/photocuba/src/frontend/node_modules/@kaiko.io/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.6 -uncurried -absname -bs-ast -o $out $i
5
- o tests/index.ast : astj ../../tests/index.res
6
- rule deps_dev
7
- command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsb_helper.exe -g -hash 84aecc33f8594375b23a1a137b057f93 $in
8
- restat = 1
9
- o tests/index.d : deps_dev tests/index.ast
10
- rule mij_dev
11
- command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsc.exe -I tests -I src/ -I /home/manu/src/kaiko/rescript-deser/node_modules/@kaiko.io/rescript-prelude/lib/ocaml -warn-error +8+11+26+27+33+56 -uncurried -bs-package-name @kaiko.io/rescript-deser -bs-package-output commonjs:lib/js/$in_d:.js -bs-package-output es6:lib/es6/$in_d:.js -bs-v $g_finger $i
12
- dyndep = 1
13
- restat = 1
14
- o tests/index.cmj tests/index.cmi ../es6/tests/index.js ../js/tests/index.js : mij_dev tests/index.ast
15
- o tests/QUnit.ast : astj ../../tests/QUnit.res
16
- o tests/QUnit.d : deps_dev tests/QUnit.ast
17
- o tests/QUnit.cmj tests/QUnit.cmi ../es6/tests/QUnit.js ../js/tests/QUnit.js : mij_dev tests/QUnit.ast
4
+ command = /home/manu/src/merchise/web/photocuba/src/frontend/node_modules/rescript/linux/bsc.exe -w a -bs-v 11.0.0-rc.6 -bs-jsx 4 -bs-jsx-mode automatic -absname -bs-ast -o $out $i
18
5
  o src/JSON.ast : astj ../../src/JSON.res
19
6
  rule deps
20
- command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsb_helper.exe -hash 84aecc33f8594375b23a1a137b057f93 $in
7
+ command = /home/manu/src/merchise/web/photocuba/src/frontend/node_modules/rescript/linux/bsb_helper.exe -hash 7f20b6808a5e3c49da192de14dbbf393 $in
21
8
  restat = 1
22
9
  o src/JSON.d : deps src/JSON.ast
23
10
  rule mij
24
- command = /home/manu/src/kaiko/rescript-deser/node_modules/rescript/linux/bsc.exe -I src/ -I /home/manu/src/kaiko/rescript-deser/node_modules/@kaiko.io/rescript-prelude/lib/ocaml -warn-error +8+11+26+27+33+56 -uncurried -bs-package-name @kaiko.io/rescript-deser -bs-package-output commonjs:lib/js/$in_d:.js -bs-package-output es6:lib/es6/$in_d:.js -bs-v $g_finger $i
11
+ command = /home/manu/src/merchise/web/photocuba/src/frontend/node_modules/rescript/linux/bsc.exe -I src/ -I /home/manu/src/merchise/web/photocuba/src/frontend/node_modules/@kaiko.io/rescript-deser/node_modules/@kaiko.io/rescript-prelude/lib/ocaml -w a -bs-package-name @kaiko.io/rescript-deser -bs-package-output es6:lib/es6/$in_d:.js -bs-v $g_finger $i
25
12
  dyndep = 1
26
13
  restat = 1
27
- o src/JSON.cmj src/JSON.cmi ../es6/src/JSON.js ../js/src/JSON.js : mij src/JSON.ast
14
+ o src/JSON.cmj src/JSON.cmi ../es6/src/JSON.js : mij src/JSON.ast
Binary file
Binary file
Binary file
Binary file
@@ -606,7 +606,7 @@ var Field = {
606
606
 
607
607
  function MakeDeserializer(S) {
608
608
  var fields = S.fields;
609
- var name = "Deserializer " + "JSON" + ", " + "File \"JSON.res\", line 329, characters 39-47";
609
+ var name = "Deserializer " + "JSON" + ", " + "File \"JSON.res\", line 320, characters 39-47";
610
610
  var checkFieldsSanity$1 = function () {
611
611
  return checkFieldsSanity(name, fields, false);
612
612
  };
@@ -630,35 +630,9 @@ function MakeDeserializer(S) {
630
630
  _0: res
631
631
  };
632
632
  };
633
- var fromAny = function (any) {
634
- var match = typeof any;
635
- if (match === "string") {
636
- var parsed;
637
- try {
638
- parsed = JSON.parse(any);
639
- }
640
- catch (exn){
641
- return {
642
- TAG: "Error",
643
- _0: "Could parse string as JSON"
644
- };
645
- }
646
- return fromJSON(parsed);
647
- }
648
- try {
649
- return fromJSON(any);
650
- }
651
- catch (exn$1){
652
- return {
653
- TAG: "Error",
654
- _0: "Could not deserialize the data"
655
- };
656
- }
657
- };
658
633
  return {
659
634
  name: name,
660
635
  fromJSON: fromJSON,
661
- fromAny: fromAny,
662
636
  checkFieldsSanity: checkFieldsSanity$1
663
637
  };
664
638
  }
@@ -0,0 +1,2 @@
1
+ #Start(1700763106532)
2
+ #Done(1700763106537)
@@ -0,0 +1,6 @@
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
Binary file
Binary file
Binary file
@@ -0,0 +1,343 @@
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaiko.io/rescript-deser",
3
- "version": "4.0.0-rc.2",
3
+ "version": "4.0.0-rc.3",
4
4
  "keywords": [
5
5
  "json",
6
6
  "deserializer",
package/src/JSON.res CHANGED
@@ -23,20 +23,11 @@ module FieldValue = {
23
23
 
24
24
  exception TypeError(string)
25
25
 
26
- @doc("The module type of a deserializer which is suitable to add as a subparser.")
27
- module type ArgDeserializer = {
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
- @doc("The module type of a built deserializer.")
26
+ @doc("The module type of a built deserializer which is suitable to add as a subparser.")
35
27
  module type Deserializer = {
36
28
  type t
37
29
  let name: string
38
30
  let fromJSON: Js.Json.t => result<t, string>
39
- let fromAny: 'a => result<t, string>
40
31
  let checkFieldsSanity: unit => result<unit, string>
41
32
  }
42
33
 
@@ -66,13 +57,13 @@ module Field = {
66
57
  /// expected entries.
67
58
  | Mapping(t)
68
59
 
69
- | Deserializer(module(ArgDeserializer))
60
+ | Deserializer(module(Deserializer))
70
61
 
71
62
  /// A specialized Array of deserialized items that ignores unparsable
72
63
  /// items and returns the valid collection. This saves the user from
73
64
  /// writing 'Array(DefaultWhenInvalid(Optional(Deserializer(module(M)))))'
74
65
  /// and then post-process the list of items with 'Array.keepSome'
75
- | Collection(module(ArgDeserializer))
66
+ | Collection(module(Deserializer))
76
67
  | DefaultWhenInvalid(t, FieldValue.t)
77
68
 
78
69
  // FIXME: this is used to add additional restrictions like variadictInt or
@@ -121,7 +112,7 @@ module Field = {
121
112
  | Date => "Date"
122
113
  | Self => "Self (recursive)"
123
114
  | Collection(m) => {
124
- module M = unpack(m: ArgDeserializer)
115
+ module M = unpack(m: Deserializer)
125
116
  "Collection of " ++ M.name
126
117
  }
127
118
 
@@ -138,7 +129,7 @@ module Field = {
138
129
  | Mapping(t) => `Mapping of ${t->toString}`
139
130
  | Morphism(t, _) => t->toString ++ " to apply a morphism"
140
131
  | Deserializer(m) => {
141
- module M = unpack(m: ArgDeserializer)
132
+ module M = unpack(m: Deserializer)
142
133
  M.name
143
134
  }
144
135
 
@@ -243,7 +234,7 @@ module Field = {
243
234
  | (Morphism(shape, f), _) => untagged->fromUntagged(shape, self)->f->FieldValue.any
244
235
 
245
236
  | (Collection(m), Js.Json.JSONArray(items)) => {
246
- module M = unpack(m: ArgDeserializer)
237
+ module M = unpack(m: Deserializer)
247
238
  items
248
239
  ->Array.map(M.fromJSON)
249
240
  ->Array.map(Result.warn)
@@ -253,7 +244,7 @@ module Field = {
253
244
  }
254
245
 
255
246
  | (Deserializer(m), _) => {
256
- module M = unpack(m: ArgDeserializer)
247
+ module M = unpack(m: Deserializer)
257
248
  switch untagged->M.fromJSON {
258
249
  | Ok(res) => res->FieldValue.any
259
250
  | Error(msg) => raise(TypeError(msg))
@@ -286,7 +277,7 @@ module Field = {
286
277
 
287
278
  | (Collection(mod), _)
288
279
  | (Deserializer(mod), _) => {
289
- module M = unpack(mod: ArgDeserializer)
280
+ module M = unpack(mod: Deserializer)
290
281
  switch M.checkFieldsSanity() {
291
282
  | Ok() => Ok()
292
283
  | Error(msg) => Error(`${name}/ ${msg}`)
@@ -329,10 +320,7 @@ module MakeDeserializer = (S: Serializable): (Deserializer with type t = S.t) =>
329
320
  %%private(let (loc, _f) = __LOC_OF__(module(S: Serializable)))
330
321
  let name = `Deserializer ${__MODULE__}, ${loc}`
331
322
 
332
- %%private(
333
- external _toNativeType: FieldValue.t => t = "%identity"
334
- external cast: 'a => 'b = "%identity"
335
- )
323
+ %%private(external _toNativeType: FieldValue.t => t = "%identity")
336
324
 
337
325
  @doc("Checks for trivial infinite-recursion in the fields of the module.
338
326
 
@@ -352,20 +340,4 @@ module MakeDeserializer = (S: Serializable): (Deserializer with type t = S.t) =>
352
340
  | exception TypeError(e) => Error(e)
353
341
  }
354
342
  }
355
-
356
- @doc("Try to parse anything")
357
- let fromAny = any => {
358
- switch Js.typeof(any) {
359
- | "string" =>
360
- switch any->cast->Js.Json.parseExn {
361
- | parsed => fromJSON(parsed)
362
- | exception _ => Error("Could parse string as JSON")
363
- }
364
- | _ =>
365
- switch any->cast->fromJSON {
366
- | result => result
367
- | exception _ => Error("Could not deserialize the data")
368
- }
369
- }
370
- }
371
343
  }
@@ -1 +0,0 @@
1
- { "dirs" : [ "tests" , "src/" ] , "pkgs" : [ [ "@kaiko.io/rescript-prelude" , "/home/manu/src/kaiko/rescript-deser/node_modules/@kaiko.io/rescript-prelude" ] ] , "generated" : [] }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1 +0,0 @@
1
- tests/index.cmj : src/JSON.cmj src/JSON.cmi tests/QUnit.cmj tests/QUnit.cmi
@@ -1,2 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
- /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */