@fncts/schema 0.0.16 → 0.0.17

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.
Files changed (151) hide show
  1. package/AST.d.ts +19 -6
  2. package/ASTAnnotation.d.ts +10 -2
  3. package/ParseError/ParseError.d.ts +231 -0
  4. package/ParseError/ParseErrorFormatter.d.ts +2 -0
  5. package/ParseError/PathFormatter.d.ts +13 -0
  6. package/ParseError/TreeFormatter.d.ts +14 -0
  7. package/ParseError.d.ts +4 -144
  8. package/ParseResult.d.ts +1 -8
  9. package/Parser/interpreter.d.ts +0 -1
  10. package/Schema/api/conc.d.ts +0 -2
  11. package/Schema/api/hashMap.d.ts +0 -1
  12. package/Schema/api/hashSet.d.ts +0 -1
  13. package/Schema/api/immutableArray.d.ts +0 -1
  14. package/Schema/api/list.d.ts +1 -2
  15. package/Schema/api/map.d.ts +19 -0
  16. package/Schema/api/set.d.ts +19 -0
  17. package/Schema/api.d.ts +11 -1
  18. package/Schema.d.ts +2 -0
  19. package/Show.d.ts +7 -3
  20. package/_cjs/AST.cjs +180 -113
  21. package/_cjs/AST.cjs.map +1 -1
  22. package/_cjs/ASTAnnotation.cjs +6 -1
  23. package/_cjs/ASTAnnotation.cjs.map +1 -1
  24. package/_cjs/Gen.cjs +24 -24
  25. package/_cjs/Gen.cjs.map +1 -1
  26. package/_cjs/ParseError/ParseError.cjs +260 -0
  27. package/_cjs/ParseError/ParseError.cjs.map +1 -0
  28. package/_cjs/ParseError/ParseErrorFormatter.cjs +6 -0
  29. package/_cjs/ParseError/ParseErrorFormatter.cjs.map +1 -0
  30. package/_cjs/ParseError/PathFormatter.cjs +94 -0
  31. package/_cjs/ParseError/PathFormatter.cjs.map +1 -0
  32. package/_cjs/ParseError/TreeFormatter.cjs +123 -0
  33. package/_cjs/ParseError/TreeFormatter.cjs.map +1 -0
  34. package/_cjs/ParseError.cjs +43 -289
  35. package/_cjs/ParseError.cjs.map +1 -1
  36. package/_cjs/ParseResult.cjs +1 -10
  37. package/_cjs/ParseResult.cjs.map +1 -1
  38. package/_cjs/Parser/api.cjs +2 -2
  39. package/_cjs/Parser/api.cjs.map +1 -1
  40. package/_cjs/Parser/definition.cjs +1 -1
  41. package/_cjs/Parser/interpreter.cjs +121 -117
  42. package/_cjs/Parser/interpreter.cjs.map +1 -1
  43. package/_cjs/Schema/api/conc.cjs +35 -45
  44. package/_cjs/Schema/api/conc.cjs.map +1 -1
  45. package/_cjs/Schema/api/either.cjs +24 -30
  46. package/_cjs/Schema/api/either.cjs.map +1 -1
  47. package/_cjs/Schema/api/hashMap.cjs +41 -101
  48. package/_cjs/Schema/api/hashMap.cjs.map +1 -1
  49. package/_cjs/Schema/api/hashSet.cjs +46 -106
  50. package/_cjs/Schema/api/hashSet.cjs.map +1 -1
  51. package/_cjs/Schema/api/immutableArray.cjs +22 -48
  52. package/_cjs/Schema/api/immutableArray.cjs.map +1 -1
  53. package/_cjs/Schema/api/list.cjs +35 -52
  54. package/_cjs/Schema/api/list.cjs.map +1 -1
  55. package/_cjs/Schema/api/map.cjs +97 -0
  56. package/_cjs/Schema/api/map.cjs.map +1 -0
  57. package/_cjs/Schema/api/maybe.cjs +24 -35
  58. package/_cjs/Schema/api/maybe.cjs.map +1 -1
  59. package/_cjs/Schema/api/set.cjs +76 -0
  60. package/_cjs/Schema/api/set.cjs.map +1 -0
  61. package/_cjs/Schema/api.cjs +20 -2
  62. package/_cjs/Schema/api.cjs.map +1 -1
  63. package/_cjs/Schema.cjs +22 -0
  64. package/_cjs/Schema.cjs.map +1 -1
  65. package/_cjs/Show.cjs +106 -89
  66. package/_cjs/Show.cjs.map +1 -1
  67. package/_cjs/utils.cjs +5 -0
  68. package/_cjs/utils.cjs.map +1 -1
  69. package/_mjs/AST.mjs +177 -112
  70. package/_mjs/AST.mjs.map +1 -1
  71. package/_mjs/ASTAnnotation.mjs +5 -0
  72. package/_mjs/ASTAnnotation.mjs.map +1 -1
  73. package/_mjs/Gen.mjs +24 -24
  74. package/_mjs/Gen.mjs.map +1 -1
  75. package/_mjs/ParseError/ParseError.mjs +228 -0
  76. package/_mjs/ParseError/ParseError.mjs.map +1 -0
  77. package/_mjs/ParseError/ParseErrorFormatter.mjs +2 -0
  78. package/_mjs/ParseError/ParseErrorFormatter.mjs.map +1 -0
  79. package/_mjs/ParseError/PathFormatter.mjs +86 -0
  80. package/_mjs/ParseError/PathFormatter.mjs.map +1 -0
  81. package/_mjs/ParseError/TreeFormatter.mjs +113 -0
  82. package/_mjs/ParseError/TreeFormatter.mjs.map +1 -0
  83. package/_mjs/ParseError.mjs +6 -270
  84. package/_mjs/ParseError.mjs.map +1 -1
  85. package/_mjs/ParseResult.mjs +1 -9
  86. package/_mjs/ParseResult.mjs.map +1 -1
  87. package/_mjs/Parser/api.mjs +2 -2
  88. package/_mjs/Parser/api.mjs.map +1 -1
  89. package/_mjs/Parser/definition.mjs +1 -1
  90. package/_mjs/Parser/interpreter.mjs +121 -117
  91. package/_mjs/Parser/interpreter.mjs.map +1 -1
  92. package/_mjs/Schema/api/conc.mjs +35 -44
  93. package/_mjs/Schema/api/conc.mjs.map +1 -1
  94. package/_mjs/Schema/api/either.mjs +24 -30
  95. package/_mjs/Schema/api/either.mjs.map +1 -1
  96. package/_mjs/Schema/api/hashMap.mjs +41 -101
  97. package/_mjs/Schema/api/hashMap.mjs.map +1 -1
  98. package/_mjs/Schema/api/hashSet.mjs +46 -106
  99. package/_mjs/Schema/api/hashSet.mjs.map +1 -1
  100. package/_mjs/Schema/api/immutableArray.mjs +23 -49
  101. package/_mjs/Schema/api/immutableArray.mjs.map +1 -1
  102. package/_mjs/Schema/api/list.mjs +35 -52
  103. package/_mjs/Schema/api/list.mjs.map +1 -1
  104. package/_mjs/Schema/api/map.mjs +88 -0
  105. package/_mjs/Schema/api/map.mjs.map +1 -0
  106. package/_mjs/Schema/api/maybe.mjs +24 -35
  107. package/_mjs/Schema/api/maybe.mjs.map +1 -1
  108. package/_mjs/Schema/api/set.mjs +67 -0
  109. package/_mjs/Schema/api/set.mjs.map +1 -0
  110. package/_mjs/Schema/api.mjs +18 -2
  111. package/_mjs/Schema/api.mjs.map +1 -1
  112. package/_mjs/Schema.mjs +2 -0
  113. package/_mjs/Schema.mjs.map +1 -1
  114. package/_mjs/Show.mjs +106 -90
  115. package/_mjs/Show.mjs.map +1 -1
  116. package/_mjs/utils.mjs +4 -0
  117. package/_mjs/utils.mjs.map +1 -1
  118. package/_src/AST.ts +144 -43
  119. package/_src/ASTAnnotation.ts +8 -1
  120. package/_src/Gen.ts +12 -9
  121. package/_src/ParseError/ParseError.ts +304 -0
  122. package/_src/ParseError/ParseErrorFormatter.ts +1 -0
  123. package/_src/ParseError/PathFormatter.ts +117 -0
  124. package/_src/ParseError/TreeFormatter.ts +127 -0
  125. package/_src/ParseError.ts +7 -331
  126. package/_src/ParseResult.ts +2 -9
  127. package/_src/Parser/api.ts +1 -1
  128. package/_src/Parser/interpreter.ts +98 -75
  129. package/_src/Schema/api/conc.ts +33 -42
  130. package/_src/Schema/api/either.ts +20 -30
  131. package/_src/Schema/api/hashMap.ts +40 -124
  132. package/_src/Schema/api/hashSet.ts +31 -117
  133. package/_src/Schema/api/immutableArray.ts +15 -45
  134. package/_src/Schema/api/list.ts +32 -55
  135. package/_src/Schema/api/map.ts +93 -0
  136. package/_src/Schema/api/maybe.ts +19 -34
  137. package/_src/Schema/api/set.ts +74 -0
  138. package/_src/Schema/api.ts +20 -2
  139. package/_src/Schema.ts +2 -0
  140. package/_src/Show.ts +156 -128
  141. package/_src/global.ts +0 -4
  142. package/_src/utils.ts +5 -0
  143. package/global.d.ts +0 -4
  144. package/package.json +2 -2
  145. package/utils.d.ts +1 -0
  146. package/ParseFailure.d.ts +0 -18
  147. package/_cjs/ParseFailure.cjs +0 -28
  148. package/_cjs/ParseFailure.cjs.map +0 -1
  149. package/_mjs/ParseFailure.mjs +0 -20
  150. package/_mjs/ParseFailure.mjs.map +0 -1
  151. package/_src/ParseFailure.ts +0 -18
@@ -1,3 +1,4 @@
1
+ import type { IndexError, KeyError, TypeError, TypeLiteralError, UnionMemberError } from "../ParseError/ParseError.js";
1
2
  import type { MutableVector } from "@fncts/base/collection/immutable/Vector";
2
3
  import type { Validation } from "@fncts/base/data/Branded";
3
4
 
@@ -14,7 +15,7 @@ import {
14
15
  } from "@fncts/base/util/predicates";
15
16
 
16
17
  import { ASTTag, concrete, getSearchTree } from "../AST.js";
17
- import { RefinementError, TransformationError } from "../ParseError.js";
18
+ import { DeclarationError, ParseErrorTag, RefinementError, TransformationError } from "../ParseError/ParseError.js";
18
19
  import { getKeysForIndexSignature, getTemplateLiteralRegex, memoize, ownKeys } from "../utils.js";
19
20
 
20
21
  const decodeMemoMap = globalValue(
@@ -41,8 +42,13 @@ function goMemo(ast: AST, isDecoding: boolean): Parser<any> {
41
42
  function go(ast: AST, isDecoding: boolean): Parser<any> {
42
43
  concrete(ast);
43
44
  switch (ast._tag) {
44
- case ASTTag.Declaration:
45
- return Parser.make(ast.decode(...ast.typeParameters));
45
+ case ASTTag.Declaration: {
46
+ const parse = isDecoding ? ast.decode(...ast.typeParameters) : ast.encode(...ast.typeParameters);
47
+
48
+ return Parser.make((input, options) =>
49
+ parse(input, options).mapLeft((error) => new DeclarationError(ast, input, error)),
50
+ );
51
+ }
46
52
  case ASTTag.Literal:
47
53
  return Parser.fromRefinement(ast, (u): u is typeof ast.literal => u === ast.literal);
48
54
  case ASTTag.UniqueSymbol:
@@ -81,18 +87,18 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
81
87
  return ParseResult.fail(ParseError.TypeError(AST.unknownArray, input));
82
88
  }
83
89
  const output: Array<any> = [];
84
- const errors: MutableVector<ParseError> = Vector.emptyPushable();
90
+ const errors: MutableVector<IndexError> = Vector.emptyPushable();
85
91
  const allErrors = options?.allErrors;
86
92
  let i = 0;
87
93
  for (; i < elements.length; i++) {
88
94
  if (input.length < i + 1) {
89
95
  if (!ast.elements[i]!.isOptional) {
90
- const e = ParseError.IndexError(i, Vector(ParseError.MissingError));
91
- errors.push(e);
96
+ const e = ParseError.IndexError(i, ParseError.MissingError);
92
97
  if (allErrors) {
98
+ errors.push(e);
93
99
  continue;
94
100
  } else {
95
- return ParseResult.failures(errors);
101
+ return ParseResult.fail(ParseError.TupleError(ast, input, Vector(e), output));
96
102
  }
97
103
  }
98
104
  } else {
@@ -100,12 +106,12 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
100
106
  const t = parser(input[i], options);
101
107
  Either.concrete(t);
102
108
  if (t.isLeft()) {
103
- const e = ParseError.IndexError(i, t.left.errors);
104
- errors.push(e);
109
+ const e = ParseError.IndexError(i, t.left);
105
110
  if (allErrors) {
111
+ errors.push(e);
106
112
  continue;
107
113
  } else {
108
- return ParseResult.failures(errors);
114
+ return ParseResult.fail(ParseError.TupleError(ast, input, Vector(e), output));
109
115
  }
110
116
  }
111
117
  output.push(t.right);
@@ -119,12 +125,12 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
119
125
  const t = head(input[i], options);
120
126
  Either.concrete(t);
121
127
  if (t.isLeft()) {
122
- const e = ParseError.IndexError(i, t.left.errors);
123
- errors.push(e);
128
+ const e = ParseError.IndexError(i, t.left);
124
129
  if (allErrors) {
130
+ errors.push(e);
125
131
  continue;
126
132
  } else {
127
- return ParseResult.failures(errors);
133
+ return ParseResult.fail(ParseError.TupleError(ast, input, Vector(e), output));
128
134
  }
129
135
  }
130
136
  output.push(t.right);
@@ -132,18 +138,23 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
132
138
  for (let j = 0; j < tail.length; j++) {
133
139
  i += j;
134
140
  if (input.length < i + 1) {
135
- errors.push(ParseError.IndexError(i, Vector(ParseError.MissingError)));
136
- return ParseResult.failures(errors);
141
+ const e = ParseError.IndexError(i, ParseError.MissingError);
142
+ if (allErrors) {
143
+ errors.push(e);
144
+ continue;
145
+ } else {
146
+ return ParseResult.fail(ParseError.TupleError(ast, input, Vector(e), output));
147
+ }
137
148
  } else {
138
149
  const t = tail[j]!(input[i], options);
139
150
  Either.concrete(t);
140
151
  if (t.isLeft()) {
141
- const e = ParseError.IndexError(i, t.left.errors);
142
- errors.push(e);
152
+ const e = ParseError.IndexError(i, t.left);
143
153
  if (allErrors) {
154
+ errors.push(e);
144
155
  continue;
145
156
  } else {
146
- return ParseResult.failures(errors);
157
+ return ParseResult.fail(ParseError.TupleError(ast, input, Vector(e), output));
147
158
  }
148
159
  }
149
160
  output.push(t.right);
@@ -152,18 +163,20 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
152
163
  } else {
153
164
  const isUnexpectedAllowed = options?.isUnexpectedAllowed;
154
165
  for (; i < input.length; i++) {
155
- const e = ParseError.IndexError(i, Vector(ParseError.UnexpectedError(input[i])));
166
+ const e = ParseError.IndexError(i, ParseError.UnexpectedError(input[i]));
156
167
  if (!isUnexpectedAllowed) {
157
- errors.push(e);
158
168
  if (allErrors) {
169
+ errors.push(e);
159
170
  continue;
160
171
  } else {
161
- return ParseResult.failures(errors);
172
+ return ParseResult.fail(ParseError.TupleError(ast, input, Vector(e), output));
162
173
  }
163
174
  }
164
175
  }
165
176
  }
166
- return errors.isNonEmpty() ? ParseResult.failures(errors) : ParseResult.succeed(output);
177
+ return errors.isNonEmpty()
178
+ ? ParseResult.fail(ParseError.TupleError(ast, input, errors, output))
179
+ : ParseResult.succeed(output);
167
180
  });
168
181
  }
169
182
  case ASTTag.TypeLiteral: {
@@ -178,9 +191,9 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
178
191
  if (!isRecord(input)) {
179
192
  return ParseResult.fail(ParseError.TypeError(AST.unknownRecord, input));
180
193
  }
181
- const output: any = {};
182
- const expectedKeys: any = {};
183
- const errors: MutableVector<ParseError> = Vector.emptyPushable();
194
+ const output: any = {};
195
+ const expectedKeys: any = {};
196
+ const errors: MutableVector<KeyError> = Vector.emptyPushable();
184
197
  const allErrors = options?.allErrors;
185
198
 
186
199
  for (let i = 0; i < propertySignatureTypes.length; i++) {
@@ -190,24 +203,24 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
190
203
  expectedKeys[name] = null;
191
204
  if (!Object.prototype.hasOwnProperty.call(input, name)) {
192
205
  if (!ps.isOptional) {
193
- const e = ParseError.KeyError(AST.createKey(name), name, Vector(ParseError.MissingError));
194
- errors.push(e);
206
+ const e = ParseError.KeyError(AST.createKey(name), name, ParseError.MissingError);
195
207
  if (allErrors) {
208
+ errors.push(e);
196
209
  continue;
197
210
  } else {
198
- return ParseResult.failures(errors);
211
+ return ParseResult.fail(ParseError.TypeLiteralError(ast, input, Vector(e), output));
199
212
  }
200
213
  }
201
214
  } else {
202
215
  const t: ParseResult<unknown> = parser(input[name], options);
203
216
  Either.concrete(t);
204
217
  if (t.isLeft()) {
205
- const e = ParseError.KeyError(AST.createKey(name), name, t.left.errors);
206
- errors.push(e);
218
+ const e = ParseError.KeyError(AST.createKey(name), name, t.left);
207
219
  if (allErrors) {
220
+ errors.push(e);
208
221
  continue;
209
222
  } else {
210
- return ParseResult.failures(errors);
223
+ return ParseResult.fail(ParseError.TypeLiteralError(ast, input, Vector(e), output));
211
224
  }
212
225
  }
213
226
  output[name] = t.right;
@@ -226,24 +239,24 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
226
239
  let t = parameter(key, options);
227
240
  Either.concrete(t);
228
241
  if (t.isLeft()) {
229
- const e = ParseError.KeyError(AST.createKey(key), key, t.left.errors);
230
- errors.push(e);
242
+ const e = ParseError.KeyError(AST.createKey(key), key, t.left);
231
243
  if (allErrors) {
244
+ errors.push(e);
232
245
  continue;
233
246
  } else {
234
- return ParseResult.failures(errors);
247
+ return ParseResult.fail(ParseError.TypeLiteralError(ast, input, Vector(e), output));
235
248
  }
236
249
  }
237
250
 
238
251
  t = type(input[key], options);
239
252
  Either.concrete(t);
240
253
  if (t.isLeft()) {
241
- const e = ParseError.KeyError(AST.createKey(key), key, t.left.errors);
254
+ const e = ParseError.KeyError(AST.createKey(key), key, t.left);
242
255
  errors.push(e);
243
256
  if (allErrors) {
244
257
  continue;
245
258
  } else {
246
- return ParseResult.failures(errors);
259
+ return ParseResult.fail(ParseError.TypeLiteralError(ast, input, Vector(e), output));
247
260
  }
248
261
  }
249
262
 
@@ -254,33 +267,36 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
254
267
  const isUnexpectedAllowed = options?.isUnexpectedAllowed;
255
268
  for (const key of ownKeys(input)) {
256
269
  if (!Object.prototype.hasOwnProperty.call(expectedKeys, key)) {
257
- const e = ParseError.KeyError(AST.createKey(key), key, Vector(ParseError.UnexpectedError(input[key])));
258
270
  if (!isUnexpectedAllowed) {
259
- errors.push(e);
271
+ const e = ParseError.KeyError(AST.createKey(key), key, ParseError.UnexpectedError(input[key]));
260
272
  if (allErrors) {
273
+ errors.push(e);
261
274
  continue;
262
275
  } else {
263
- return ParseResult.failures(errors);
276
+ return ParseResult.fail(ParseError.TypeLiteralError(ast, input, Vector(e), output));
264
277
  }
265
278
  }
266
279
  }
267
280
  }
268
281
  }
269
282
 
270
- return errors.isNonEmpty() ? ParseResult.failures(errors) : ParseResult.succeed(output);
283
+ return errors.isNonEmpty()
284
+ ? ParseResult.fail(ParseError.TypeLiteralError(ast, input, errors, output))
285
+ : ParseResult.succeed(output);
271
286
  });
272
287
  }
273
288
  case ASTTag.Union: {
274
289
  const searchTree = getSearchTree(ast.types, isDecoding);
275
290
  const ownKeys = Reflect.ownKeys(searchTree.keys);
276
291
  const len = ownKeys.length;
277
- const otherwise = searchTree.otherwise;
278
292
  const map = new Map<any, Parser<any>>();
279
293
  ast.types.forEach((ast) => {
280
294
  map.set(ast, goMemo(ast, isDecoding));
281
295
  });
282
296
  return Parser.make((input, options) => {
283
- const errors = Vector.emptyPushable<ParseError>();
297
+ const errors = Vector.emptyPushable<TypeError | TypeLiteralError | UnionMemberError>();
298
+ let candidates: Array<AST> = [];
299
+
284
300
  if (len > 0) {
285
301
  if (isRecord(input)) {
286
302
  for (let i = 0; i < len; i++) {
@@ -289,45 +305,58 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
289
305
  if (Object.prototype.hasOwnProperty.call(input, name)) {
290
306
  const literal = String(input[name]);
291
307
  if (Object.prototype.hasOwnProperty.call(buckets, literal)) {
292
- const bucket: ReadonlyArray<AST> = buckets[literal]!;
293
- for (let i = 0; i < bucket.length; i++) {
294
- const t = map.get(bucket[i])!(input, options);
295
- Either.concrete(t);
296
- if (t.isRight()) {
297
- return t;
298
- } else {
299
- errors.push(ParseError.UnionMemberError(t.left.errors));
300
- }
301
- }
308
+ candidates = candidates.concat(buckets[literal]!);
302
309
  } else {
310
+ const literals = AST.createUnion(Vector.from(searchTree.keys[name]!.literals));
303
311
  errors.push(
304
- ParseError.KeyError(
305
- AST.createKey(name),
306
- name,
307
- Vector(ParseError.TypeError(searchTree.keys[name]!.ast, input[name])),
312
+ ParseError.TypeLiteralError(
313
+ AST.createTypeLiteral(Vector(AST.createPropertySignature(name, literals, false, true)), Vector()),
314
+ input,
315
+ Vector(
316
+ ParseError.KeyError(
317
+ AST.createKey(name),
318
+ name,
319
+ ParseError.TypeError(searchTree.keys[name]!.ast, input[name]),
320
+ ),
321
+ ),
308
322
  ),
309
323
  );
310
324
  }
311
325
  } else {
312
- errors.push(ParseError.KeyError(AST.createKey(name), name, Vector(ParseError.MissingError)));
326
+ const literals = AST.createUnion(Vector.from(searchTree.keys[name]!.literals));
327
+ errors.push(
328
+ ParseError.TypeLiteralError(
329
+ AST.createTypeLiteral(Vector(AST.createPropertySignature(name, literals, false, true)), Vector()),
330
+ input,
331
+ Vector(ParseError.KeyError(AST.createKey(name), name, ParseError.MissingError)),
332
+ ),
333
+ );
313
334
  }
314
335
  }
315
336
  } else {
316
337
  errors.push(ParseError.TypeError(AST.unknownRecord, input));
317
338
  }
318
339
  }
319
- for (let i = 0; i < otherwise.length; i++) {
320
- const t = map.get(otherwise[i])!(input, options);
321
- Either.concrete(t);
322
- if (t.isRight()) {
323
- return t;
340
+
341
+ if (searchTree.otherwise.length > 0) {
342
+ candidates = candidates.concat(searchTree.otherwise);
343
+ }
344
+
345
+ for (let i = 0; i < candidates.length; i++) {
346
+ const candidate = candidates[i]!;
347
+ const pr = map.get(candidate)!(input, options);
348
+ Either.concrete(pr);
349
+ if (pr.isRight()) {
350
+ return pr;
324
351
  } else {
325
- errors.push(ParseError.UnionMemberError(t.left.errors));
352
+ errors.push(ParseError.UnionMemberError(candidate, pr.left));
326
353
  }
327
354
  }
328
355
 
329
356
  return errors.isNonEmpty()
330
- ? ParseResult.failures(errors)
357
+ ? errors.length === 1 && errors[0]!._tag === ParseErrorTag.Type
358
+ ? ParseResult.fail(errors[0]! as TypeError)
359
+ : ParseResult.fail(ParseError.UnionError(ast, input, Vector.from(errors)))
331
360
  : ParseResult.fail(ParseError.TypeError(AST.neverKeyword, input));
332
361
  });
333
362
  }
@@ -341,11 +370,9 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
341
370
  const from = goMemo(ast.from, isDecoding);
342
371
  return Parser.make((input, options) =>
343
372
  from(input, options)
344
- .mapLeft((failure) => ParseFailure(Vector(RefinementError(ast, input, "From", failure.errors))))
373
+ .mapLeft((failure) => RefinementError(ast, input, "From", failure))
345
374
  .flatMap((a) =>
346
- ast
347
- .decode(a, options)
348
- .mapLeft((failure) => ParseFailure(Vector(RefinementError(ast, input, "Predicate", failure.errors)))),
375
+ ast.decode(a, options).mapLeft((failure) => RefinementError(ast, input, "Predicate", failure)),
349
376
  ),
350
377
  );
351
378
  } else {
@@ -364,17 +391,13 @@ function go(ast: AST, isDecoding: boolean): Parser<any> {
364
391
  const to = isDecoding ? goMemo(ast.to, true) : goMemo(ast.from, false);
365
392
  return Parser.make((input, options) =>
366
393
  from(input, options)
367
- .mapLeft((failure) =>
368
- ParseFailure(Vector(TransformationError(ast, input, isDecoding ? "Encoded" : "Type", failure.errors))),
369
- )
394
+ .mapLeft((failure) => TransformationError(ast, input, isDecoding ? "Encoded" : "Type", failure))
370
395
  .flatMap((a) =>
371
- transformation(a, options).mapLeft((failure) =>
372
- ParseFailure(Vector(TransformationError(ast, input, "Transformation", failure.errors))),
373
- ),
396
+ transformation(a, options).mapLeft((failure) => TransformationError(ast, input, "Transformation", failure)),
374
397
  )
375
398
  .flatMap((a) =>
376
399
  to(a, options).mapLeft((failure) =>
377
- ParseFailure(Vector(TransformationError(ast, input, isDecoding ? "Type" : "Encoded", failure.errors))),
400
+ TransformationError(ast, input, isDecoding ? "Type" : "Encoded", failure),
378
401
  ),
379
402
  ),
380
403
  );
@@ -1,14 +1,10 @@
1
+ import type { IndexError } from "@fncts/schema/ParseError";
1
2
  import type { Sized } from "@fncts/test/control/Sized";
2
3
 
3
- import { ConcTypeId } from "@fncts/base/collection/immutable/Conc";
4
-
5
4
  export function conc<A>(value: Schema<A>): Schema<Conc<A>> {
6
- return Schema.declaration(
7
- Vector(value),
8
- inline(value),
9
- concParser,
10
- ASTAnnotationMap.empty.annotate(ASTAnnotation.Identifier, "Conc").annotate(ASTAnnotation.GenHook, gen),
11
- );
5
+ return Schema.declaration(Vector(value), concParser(true), concParser(false))
6
+ .annotate(ASTAnnotation.Identifier, `Conc<${value.show()}>`)
7
+ .annotate(ASTAnnotation.GenHook, gen);
12
8
  }
13
9
 
14
10
  /**
@@ -35,42 +31,37 @@ export function deriveConc<A extends Conc<any>>(
35
31
  return unsafeCoerce(concFromArray(value));
36
32
  }
37
33
 
38
- export function concParser<A>(value: Schema<A>): Parser<Conc<A>> {
39
- const schema = conc(value);
40
- return Parser.make((u, options) => {
41
- if (!Conc.is(u)) {
42
- return ParseResult.fail(ParseError.TypeError(schema.ast, u));
43
- }
44
- const allErrors = options?.allErrors;
45
- const errors = Vector.emptyPushable<ParseError>();
46
- const out: Array<A> = [];
47
- let i = 0;
48
- for (const v of u) {
49
- const t = value.decode(v);
50
- Either.concrete(t);
51
- if (t.isLeft()) {
52
- errors.push(ParseError.IndexError(i, t.left.errors));
53
- if (!allErrors) {
54
- return ParseResult.failures(errors);
55
- }
56
- } else {
57
- out.push(t.right);
34
+ function concParser(isDecoding: boolean) {
35
+ return <A>(value: Schema<A>): Parser<Conc<unknown>> => {
36
+ const schema = conc(value);
37
+ return Parser.make((u, options) => {
38
+ if (!Conc.is(u)) {
39
+ return ParseResult.fail(ParseError.TypeError(schema.ast, u));
58
40
  }
59
- i++;
60
- }
61
- return errors.isNonEmpty() ? ParseResult.failures(errors) : ParseResult.succeed(Conc.fromArray(out));
62
- });
63
- }
41
+ const allErrors = options?.allErrors;
42
+ const errors = Vector.emptyPushable<IndexError>();
43
+ const out: Array<unknown> = [];
44
+ let i = 0;
64
45
 
65
- function inline<A>(_value: Schema<A>): Schema<Conc<A>> {
66
- return Schema.struct({
67
- _A: Schema.any,
68
- [ConcTypeId]: Schema.uniqueSymbol(ConcTypeId),
69
- length: Schema.number,
70
- [Symbol.iterator]: Schema.any,
71
- [Symbol.hash]: Schema.any,
72
- [Symbol.equals]: Schema.any,
73
- });
46
+ for (const v of u) {
47
+ const parser = isDecoding ? value.decode : value.encode;
48
+ const t = parser(v, options);
49
+ Either.concrete(t);
50
+ if (t.isLeft()) {
51
+ errors.push(ParseError.IndexError(i, t.left));
52
+ if (!allErrors) {
53
+ return ParseResult.fail(ParseError.IterableError(schema.ast, u, errors));
54
+ }
55
+ } else {
56
+ out.push(t.right);
57
+ }
58
+ i++;
59
+ }
60
+ return errors.isNonEmpty()
61
+ ? ParseResult.fail(ParseError.IterableError(schema.ast, u, errors))
62
+ : ParseResult.succeed(Conc.from(out));
63
+ });
64
+ };
74
65
  }
75
66
 
76
67
  function gen<A>(value: Gen<Sized, A>): Gen<Sized, Conc<A>> {
@@ -1,17 +1,12 @@
1
1
  import type { EitherJson } from "@fncts/base/json/EitherJson";
2
2
 
3
- import { EitherTypeId, EitherVariance } from "@fncts/base/data/Either";
4
- import { IOTypeId } from "@fncts/io/IO";
5
-
6
3
  /**
7
4
  * @tsplus static fncts.schema.SchemaOps either
8
5
  */
9
6
  export function either<E, A>(left: Schema<E>, right: Schema<A>): Schema<Either<E, A>> {
10
- return Schema.declaration(
11
- Vector(left, right),
12
- eitherInline(left, right),
13
- eitherParser,
14
- ASTAnnotationMap.empty.annotate(ASTAnnotation.Identifier, "Either"),
7
+ return Schema.declaration(Vector(left, right), eitherParser(true), eitherParser(false)).annotate(
8
+ ASTAnnotation.Identifier,
9
+ `Either<${left.show()}, ${right.show()}>`,
15
10
  );
16
11
  }
17
12
 
@@ -71,26 +66,21 @@ export function deriveEither<A extends Either<any, any>>(
71
66
  return unsafeCoerce(eitherFromJson(left, right));
72
67
  }
73
68
 
74
- function eitherParser<E, A>(left: Schema<E>, right: Schema<A>): Parser<Either<E, A>> {
75
- const schema = either(left, right);
76
- return Parser.make((u, options) => {
77
- if (!Either.isEither(u)) {
78
- return ParseResult.fail(ParseError.TypeError(schema.ast, u));
79
- }
80
- Either.concrete(u);
81
- if (u.isLeft()) {
82
- return left.decode(u.left, options).map(Either.left);
83
- } else {
84
- return right.decode(u.right, options).map(Either.right);
85
- }
86
- });
87
- }
88
-
89
- function eitherInline<E, A>(_left: Schema<E>, _right: Schema<A>): Schema<Either<E, A>> {
90
- return Schema.struct({
91
- [EitherTypeId]: Schema.uniqueSymbol(EitherTypeId),
92
- [EitherVariance]: Schema.any,
93
- [IOTypeId]: Schema.uniqueSymbol(IOTypeId),
94
- trace: Schema.undefined,
95
- }) as unknown as Schema<Either<E, A>>;
69
+ function eitherParser(isDecoding: boolean) {
70
+ return <E, A>(left: Schema<E>, right: Schema<A>): Parser<Either<unknown, unknown>> => {
71
+ const schema = either(left, right);
72
+ return Parser.make((u, options) => {
73
+ if (!Either.isEither(u)) {
74
+ return ParseResult.fail(ParseError.TypeError(schema.ast, u));
75
+ }
76
+ Either.concrete(u);
77
+ if (u.isLeft()) {
78
+ const parse = isDecoding ? left.decode : left.encode;
79
+ return parse(u.left, options).map(Either.left);
80
+ } else {
81
+ const parse = isDecoding ? right.decode : right.encode;
82
+ return parse(u.right, options).map(Either.right);
83
+ }
84
+ });
85
+ };
96
86
  }