@fncts/schema 0.0.16 → 0.0.18

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 (173) 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 +181 -114
  21. package/_cjs/AST.cjs.map +1 -1
  22. package/_cjs/ASTAnnotation.cjs +7 -2
  23. package/_cjs/ASTAnnotation.cjs.map +1 -1
  24. package/_cjs/ASTAnnotationMap.cjs +1 -1
  25. package/_cjs/ASTAnnotationMap.cjs.map +1 -1
  26. package/_cjs/Gen.cjs +25 -25
  27. package/_cjs/Gen.cjs.map +1 -1
  28. package/_cjs/Guard.cjs +1 -1
  29. package/_cjs/Guard.cjs.map +1 -1
  30. package/_cjs/InvalidInterpretationError.cjs.map +1 -1
  31. package/_cjs/ParseError/ParseError.cjs +260 -0
  32. package/_cjs/ParseError/ParseError.cjs.map +1 -0
  33. package/_cjs/ParseError/ParseErrorFormatter.cjs +6 -0
  34. package/_cjs/ParseError/ParseErrorFormatter.cjs.map +1 -0
  35. package/_cjs/ParseError/PathFormatter.cjs +94 -0
  36. package/_cjs/ParseError/PathFormatter.cjs.map +1 -0
  37. package/_cjs/ParseError/TreeFormatter.cjs +123 -0
  38. package/_cjs/ParseError/TreeFormatter.cjs.map +1 -0
  39. package/_cjs/ParseError.cjs +43 -289
  40. package/_cjs/ParseError.cjs.map +1 -1
  41. package/_cjs/ParseResult.cjs +2 -11
  42. package/_cjs/ParseResult.cjs.map +1 -1
  43. package/_cjs/Parser/api.cjs +3 -3
  44. package/_cjs/Parser/api.cjs.map +1 -1
  45. package/_cjs/Parser/definition.cjs +2 -2
  46. package/_cjs/Parser/definition.cjs.map +1 -1
  47. package/_cjs/Parser/interpreter.cjs +122 -118
  48. package/_cjs/Parser/interpreter.cjs.map +1 -1
  49. package/_cjs/Parser.cjs.map +1 -1
  50. package/_cjs/Schema/api/conc.cjs +36 -46
  51. package/_cjs/Schema/api/conc.cjs.map +1 -1
  52. package/_cjs/Schema/api/either.cjs +25 -31
  53. package/_cjs/Schema/api/either.cjs.map +1 -1
  54. package/_cjs/Schema/api/hashMap.cjs +42 -102
  55. package/_cjs/Schema/api/hashMap.cjs.map +1 -1
  56. package/_cjs/Schema/api/hashSet.cjs +47 -107
  57. package/_cjs/Schema/api/hashSet.cjs.map +1 -1
  58. package/_cjs/Schema/api/immutableArray.cjs +23 -49
  59. package/_cjs/Schema/api/immutableArray.cjs.map +1 -1
  60. package/_cjs/Schema/api/list.cjs +36 -53
  61. package/_cjs/Schema/api/list.cjs.map +1 -1
  62. package/_cjs/Schema/api/map.cjs +97 -0
  63. package/_cjs/Schema/api/map.cjs.map +1 -0
  64. package/_cjs/Schema/api/maybe.cjs +25 -36
  65. package/_cjs/Schema/api/maybe.cjs.map +1 -1
  66. package/_cjs/Schema/api/set.cjs +76 -0
  67. package/_cjs/Schema/api/set.cjs.map +1 -0
  68. package/_cjs/Schema/api.cjs +21 -3
  69. package/_cjs/Schema/api.cjs.map +1 -1
  70. package/_cjs/Schema/definition.cjs +1 -1
  71. package/_cjs/Schema/definition.cjs.map +1 -1
  72. package/_cjs/Schema/derivations.cjs +1 -1
  73. package/_cjs/Schema/derivations.cjs.map +1 -1
  74. package/_cjs/Schema.cjs +22 -0
  75. package/_cjs/Schema.cjs.map +1 -1
  76. package/_cjs/Show.cjs +107 -90
  77. package/_cjs/Show.cjs.map +1 -1
  78. package/_cjs/global.cjs.map +1 -1
  79. package/_cjs/index.cjs.map +1 -1
  80. package/_cjs/utils.cjs +6 -1
  81. package/_cjs/utils.cjs.map +1 -1
  82. package/_mjs/AST.mjs +177 -112
  83. package/_mjs/AST.mjs.map +1 -1
  84. package/_mjs/ASTAnnotation.mjs +5 -0
  85. package/_mjs/ASTAnnotation.mjs.map +1 -1
  86. package/_mjs/ASTAnnotationMap.mjs.map +1 -1
  87. package/_mjs/Gen.mjs +24 -24
  88. package/_mjs/Gen.mjs.map +1 -1
  89. package/_mjs/Guard.mjs.map +1 -1
  90. package/_mjs/InvalidInterpretationError.mjs.map +1 -1
  91. package/_mjs/ParseError/ParseError.mjs +228 -0
  92. package/_mjs/ParseError/ParseError.mjs.map +1 -0
  93. package/_mjs/ParseError/ParseErrorFormatter.mjs +2 -0
  94. package/_mjs/ParseError/ParseErrorFormatter.mjs.map +1 -0
  95. package/_mjs/ParseError/PathFormatter.mjs +86 -0
  96. package/_mjs/ParseError/PathFormatter.mjs.map +1 -0
  97. package/_mjs/ParseError/TreeFormatter.mjs +113 -0
  98. package/_mjs/ParseError/TreeFormatter.mjs.map +1 -0
  99. package/_mjs/ParseError.mjs +6 -270
  100. package/_mjs/ParseError.mjs.map +1 -1
  101. package/_mjs/ParseResult.mjs +1 -9
  102. package/_mjs/ParseResult.mjs.map +1 -1
  103. package/_mjs/Parser/api.mjs +2 -2
  104. package/_mjs/Parser/api.mjs.map +1 -1
  105. package/_mjs/Parser/definition.mjs +1 -1
  106. package/_mjs/Parser/definition.mjs.map +1 -1
  107. package/_mjs/Parser/interpreter.mjs +121 -117
  108. package/_mjs/Parser/interpreter.mjs.map +1 -1
  109. package/_mjs/Parser.mjs.map +1 -1
  110. package/_mjs/Schema/api/conc.mjs +35 -44
  111. package/_mjs/Schema/api/conc.mjs.map +1 -1
  112. package/_mjs/Schema/api/either.mjs +24 -30
  113. package/_mjs/Schema/api/either.mjs.map +1 -1
  114. package/_mjs/Schema/api/hashMap.mjs +41 -101
  115. package/_mjs/Schema/api/hashMap.mjs.map +1 -1
  116. package/_mjs/Schema/api/hashSet.mjs +46 -106
  117. package/_mjs/Schema/api/hashSet.mjs.map +1 -1
  118. package/_mjs/Schema/api/immutableArray.mjs +23 -49
  119. package/_mjs/Schema/api/immutableArray.mjs.map +1 -1
  120. package/_mjs/Schema/api/list.mjs +35 -52
  121. package/_mjs/Schema/api/list.mjs.map +1 -1
  122. package/_mjs/Schema/api/map.mjs +88 -0
  123. package/_mjs/Schema/api/map.mjs.map +1 -0
  124. package/_mjs/Schema/api/maybe.mjs +24 -35
  125. package/_mjs/Schema/api/maybe.mjs.map +1 -1
  126. package/_mjs/Schema/api/set.mjs +67 -0
  127. package/_mjs/Schema/api/set.mjs.map +1 -0
  128. package/_mjs/Schema/api.mjs +18 -2
  129. package/_mjs/Schema/api.mjs.map +1 -1
  130. package/_mjs/Schema/definition.mjs.map +1 -1
  131. package/_mjs/Schema/derivations.mjs.map +1 -1
  132. package/_mjs/Schema.mjs +2 -0
  133. package/_mjs/Schema.mjs.map +1 -1
  134. package/_mjs/Show.mjs +106 -90
  135. package/_mjs/Show.mjs.map +1 -1
  136. package/_mjs/global.mjs.map +1 -1
  137. package/_mjs/index.mjs.map +1 -1
  138. package/_mjs/utils.mjs +4 -0
  139. package/_mjs/utils.mjs.map +1 -1
  140. package/_src/AST.ts +139 -38
  141. package/_src/ASTAnnotation.ts +8 -1
  142. package/_src/Gen.ts +4 -1
  143. package/_src/ParseError/ParseError.ts +304 -0
  144. package/_src/ParseError/ParseErrorFormatter.ts +1 -0
  145. package/_src/ParseError/PathFormatter.ts +117 -0
  146. package/_src/ParseError/TreeFormatter.ts +127 -0
  147. package/_src/ParseError.ts +7 -331
  148. package/_src/ParseResult.ts +2 -9
  149. package/_src/Parser/api.ts +1 -1
  150. package/_src/Parser/interpreter.ts +98 -75
  151. package/_src/Schema/api/conc.ts +33 -42
  152. package/_src/Schema/api/either.ts +20 -30
  153. package/_src/Schema/api/hashMap.ts +40 -124
  154. package/_src/Schema/api/hashSet.ts +31 -117
  155. package/_src/Schema/api/immutableArray.ts +15 -45
  156. package/_src/Schema/api/list.ts +32 -55
  157. package/_src/Schema/api/map.ts +93 -0
  158. package/_src/Schema/api/maybe.ts +19 -34
  159. package/_src/Schema/api/set.ts +74 -0
  160. package/_src/Schema/api.ts +20 -2
  161. package/_src/Schema.ts +2 -0
  162. package/_src/Show.ts +156 -128
  163. package/_src/global.ts +0 -4
  164. package/_src/utils.ts +6 -0
  165. package/global.d.ts +0 -4
  166. package/package.json +3 -3
  167. package/utils.d.ts +1 -0
  168. package/ParseFailure.d.ts +0 -18
  169. package/_cjs/ParseFailure.cjs +0 -28
  170. package/_cjs/ParseFailure.cjs.map +0 -1
  171. package/_mjs/ParseFailure.mjs +0 -20
  172. package/_mjs/ParseFailure.mjs.map +0 -1
  173. package/_src/ParseFailure.ts +0 -18
@@ -1,28 +1,17 @@
1
- import type {
2
- ArrayNode,
3
- CollisionNode,
4
- EmptyNode,
5
- IndexedNode,
6
- LeafNode,
7
- Node,
8
- } from "@fncts/base/collection/immutable/HashMap/internal";
1
+ import type { KeyError } from "@fncts/schema/ParseError";
9
2
  import type { Sized } from "@fncts/test/control/Sized";
10
3
  import type { Check } from "@fncts/typelevel";
11
4
 
12
5
  import { HashMap } from "@fncts/base/collection/immutable/HashMap";
13
- import { HashMapTypeId, HashMapVariance } from "@fncts/base/collection/immutable/HashMap";
14
6
  import { ASTAnnotation } from "@fncts/schema/ASTAnnotation";
15
7
 
16
8
  /**
17
9
  * @tsplus static fncts.schema.SchemaOps hashMap
18
10
  */
19
11
  export function hashMap<K, V>(key: Schema<K>, value: Schema<V>): Schema<HashMap<K, V>> {
20
- return Schema.declaration(
21
- Vector(key, value),
22
- inline(key, value),
23
- hashMapParser,
24
- ASTAnnotationMap.empty.annotate(ASTAnnotation.Identifier, "HashMap").annotate(ASTAnnotation.GenHook, gen),
25
- );
12
+ return Schema.declaration(Vector(key, value), hashMapParser(true), hashMapParser(false))
13
+ .annotate(ASTAnnotation.Identifier, `HashMap<${key.show()}, ${value.show()}>`)
14
+ .annotate(ASTAnnotation.GenHook, gen);
26
15
  }
27
16
 
28
17
  /**
@@ -65,118 +54,45 @@ export function deriveHashMap<A extends HashMap<any, any>>(
65
54
  return unsafeCoerce(hashMapFromRecord(key as Schema<string | symbol>, value));
66
55
  }
67
56
 
68
- function hashMapParser<K, V>(key: Schema<K>, value: Schema<V>): Parser<HashMap<K, V>> {
69
- const schema = hashMap(key, value);
70
- return Parser.make((u, options) => {
71
- if (!HashMap.is(u)) {
72
- return ParseResult.fail(ParseError.TypeError(schema.ast, u));
73
- }
74
- const allErrors = options?.allErrors;
75
- const errors = Vector.emptyPushable<ParseError>();
76
- const out = HashMap.empty<K, V>().beginMutation;
77
- for (const [k, v] of u) {
78
- const tk = key.decode(k, options);
79
- Either.concrete(tk);
80
- if (tk.isLeft()) {
81
- errors.push(ParseError.KeyError(key.ast, k, tk.left.errors));
82
- if (!allErrors) {
83
- return ParseResult.failures(errors);
84
- }
57
+ function hashMapParser(isDecoding: boolean) {
58
+ return <K, V>(key: Schema<K>, value: Schema<V>): Parser<HashMap<unknown, unknown>> => {
59
+ const schema = hashMap(key, value);
60
+ return Parser.make((u, options) => {
61
+ if (!HashMap.is(u)) {
62
+ return ParseResult.fail(ParseError.TypeError(schema.ast, u));
85
63
  }
86
- const tv = value.decode(v, options);
87
- Either.concrete(tv);
88
- if (tv.isLeft()) {
89
- errors.push(ParseError.TypeError(value.ast, tv.left));
90
- if (!allErrors) {
91
- return ParseResult.failures(errors);
64
+ const allErrors = options?.allErrors;
65
+ const errors = Vector.emptyPushable<KeyError>();
66
+ const out = HashMap.empty<unknown, unknown>().beginMutation;
67
+ const keyParser = isDecoding ? key.decode : key.encode;
68
+ const valueParser = isDecoding ? value.decode : value.encode;
69
+ for (const [k, v] of u) {
70
+ const tk = keyParser(k, options);
71
+ Either.concrete(tk);
72
+ if (tk.isLeft()) {
73
+ errors.push(ParseError.KeyError(key.ast, k, tk.left));
74
+ if (!allErrors) {
75
+ return ParseResult.fail(ParseError.IterableError(schema.ast, u, errors));
76
+ }
92
77
  }
78
+ const tv = valueParser(v, options);
79
+ Either.concrete(tv);
80
+ if (tv.isLeft()) {
81
+ errors.push(ParseError.KeyError(key.ast, k, ParseError.TypeError(value.ast, tv.left)));
82
+ if (!allErrors) {
83
+ return ParseResult.fail(ParseError.IterableError(schema.ast, u, errors));
84
+ }
85
+ }
86
+ if (tk.isLeft() || tv.isLeft()) {
87
+ continue;
88
+ }
89
+ out.set(tk.right, tv.right);
93
90
  }
94
- if (tk.isLeft() || tv.isLeft()) {
95
- continue;
96
- }
97
- out.set(tk.right, tv.right);
98
- }
99
- return errors.isNonEmpty() ? ParseResult.failures(errors) : ParseResult.succeed(out.endMutation);
100
- });
101
- }
102
-
103
- function emptyNodeSchema<K, V>(_key: Schema<K>, _value: Schema<V>): Schema<EmptyNode<K, V>> {
104
- return Schema.struct({
105
- _tag: Schema.literal("EmptyNode"),
106
- modify: Schema.any,
107
- });
108
- }
109
-
110
- function leafNodeSchema<K, V>(key: Schema<K>, value: Schema<V>): Schema<LeafNode<K, V>> {
111
- return Schema.struct({
112
- _tag: Schema.literal("LeafNode"),
113
- edit: Schema.number,
114
- hash: Schema.number,
115
- key,
116
- value: value.maybe,
117
- modify: Schema.any,
118
- });
119
- }
120
-
121
- function collisionNodeSchema<K, V>(key: Schema<K>, value: Schema<V>): Schema<CollisionNode<K, V>> {
122
- return Schema.lazy(() =>
123
- Schema.struct({
124
- _tag: Schema.literal("CollisionNode"),
125
- edit: Schema.number,
126
- hash: Schema.number,
127
- children: nodeSchema(key, value).mutableArray,
128
- modify: Schema.any,
129
- }),
130
- );
131
- }
132
-
133
- function indexedNodeSchema<K, V>(key: Schema<K>, value: Schema<V>): Schema<IndexedNode<K, V>> {
134
- return Schema.lazy(() =>
135
- Schema.struct({
136
- _tag: Schema.literal("IndexedNode"),
137
- edit: Schema.number,
138
- mask: Schema.number,
139
- children: nodeSchema(key, value).mutableArray,
140
- modify: Schema.any,
141
- }),
142
- );
143
- }
144
-
145
- function arrayNodeSchema<K, V>(key: Schema<K>, value: Schema<V>): Schema<ArrayNode<K, V>> {
146
- return Schema.lazy(() =>
147
- Schema.struct({
148
- _tag: Schema.literal("ArrayNode"),
149
- edit: Schema.number,
150
- size: Schema.number,
151
- children: nodeSchema(key, value).mutableArray,
152
- modify: Schema.any,
153
- }),
154
- );
155
- }
156
-
157
- function nodeSchema<K, V>(key: Schema<K>, value: Schema<V>): Schema<Node<K, V>> {
158
- return Schema.union(
159
- emptyNodeSchema(key, value),
160
- leafNodeSchema(key, value),
161
- collisionNodeSchema(key, value),
162
- indexedNodeSchema(key, value),
163
- arrayNodeSchema(key, value),
164
- );
165
- }
166
-
167
- function inline<K, V>(key: Schema<K>, value: Schema<V>): Schema<HashMap<K, V>> {
168
- return Schema.struct({
169
- [HashMapTypeId]: Schema.uniqueSymbol(HashMapTypeId),
170
- [HashMapVariance]: Schema.any,
171
- editable: Schema.boolean,
172
- edit: Schema.number,
173
- config: Schema.any,
174
- root: nodeSchema(key, value),
175
- size: Schema.number,
176
- [Symbol.iterator]: Schema.any,
177
- [Symbol.hash]: Schema.any,
178
- [Symbol.equals]: Schema.any,
179
- });
91
+ return errors.isNonEmpty()
92
+ ? ParseResult.fail(ParseError.IterableError(schema.ast, u, errors))
93
+ : ParseResult.succeed(out.endMutation);
94
+ });
95
+ };
180
96
  }
181
97
 
182
98
  function gen<K, V>(key: Gen<Sized, K>, value: Gen<Sized, V>): Gen<Sized, HashMap<K, V>> {
@@ -1,25 +1,12 @@
1
+ import type { KeyError } from "@fncts/schema/ParseError";
1
2
  import type { Sized } from "@fncts/test/control/Sized";
2
3
 
3
- import {
4
- type ArrayNode,
5
- type CollisionNode,
6
- type EmptyNode,
7
- HashSetTypeId,
8
- HashSetVariance,
9
- type IndexedNode,
10
- type LeafNode,
11
- type Node,
12
- } from "@fncts/base/collection/immutable/HashSet/definition";
13
4
  import { ASTAnnotation } from "@fncts/schema/ASTAnnotation";
14
- import { ASTAnnotationMap } from "@fncts/schema/ASTAnnotationMap";
15
5
 
16
6
  export function hashSet<A>(value: Schema<A>): Schema<HashSet<A>> {
17
- return Schema.declaration(
18
- Vector(value),
19
- inline(value),
20
- hashSetParser,
21
- ASTAnnotationMap.empty.annotate(ASTAnnotation.Identifier, "HashMap").annotate(ASTAnnotation.GenHook, gen),
22
- );
7
+ return Schema.declaration(Vector(value), hashSetParser(true), hashSetParser(false))
8
+ .annotate(ASTAnnotation.Identifier, `HashSet<${value.show()}>`)
9
+ .annotate(ASTAnnotation.GenHook, gen);
23
10
  }
24
11
 
25
12
  /**
@@ -58,108 +45,35 @@ export function deriveHashSet<A extends HashSet<any>>(
58
45
  return unsafeCoerce(hashSetFromArray(value));
59
46
  }
60
47
 
61
- function hashSetParser<A>(value: Schema<A>): Parser<HashSet<A>> {
62
- const schema = hashSet(value);
63
- return Parser.make((u, options) => {
64
- if (!HashSet.is(u)) {
65
- return ParseResult.fail(ParseError.TypeError(schema.ast, u));
66
- }
67
- const allErrors = options?.allErrors;
68
- const errors = Vector.emptyPushable<ParseError>();
69
- const out = HashSet.empty<A>().beginMutation;
70
- for (const v of u) {
71
- const tv = value.decode(v, options);
72
- Either.concrete(tv);
73
- if (tv.isLeft()) {
74
- errors.push(ParseError.TypeError(value.ast, tv.left));
75
- if (!allErrors) {
76
- return ParseResult.failures(errors);
77
- }
78
- continue;
48
+ function hashSetParser(isDecoding: boolean) {
49
+ return <A>(value: Schema<A>): Parser<HashSet<unknown>> => {
50
+ const schema = hashSet(value);
51
+ const parseValue = isDecoding ? value.decode : value.encode;
52
+ return Parser.make((u, options) => {
53
+ if (!HashSet.is(u)) {
54
+ return ParseResult.fail(ParseError.TypeError(schema.ast, u));
79
55
  }
80
- out.add(tv.right);
81
- }
82
- return errors.isNonEmpty() ? ParseResult.failures(errors) : ParseResult.succeed(out.endMutation);
83
- });
84
- }
85
56
 
86
- function emptyNodeSchema<A>(_value: Schema<A>): Schema<EmptyNode<A>> {
87
- return Schema.struct({
88
- _tag: Schema.literal("EmptyNode"),
89
- modify: Schema.any,
90
- });
91
- }
92
-
93
- function leafNodeSchema<A>(value: Schema<A>): Schema<LeafNode<A>> {
94
- return Schema.struct({
95
- _tag: Schema.literal("LeafNode"),
96
- edit: Schema.number,
97
- hash: Schema.number,
98
- value: value,
99
- modify: Schema.any,
100
- });
101
- }
102
-
103
- function collisionNodeSchema<A>(value: Schema<A>): Schema<CollisionNode<A>> {
104
- return Schema.lazy(() =>
105
- Schema.struct({
106
- _tag: Schema.literal("CollisionNode"),
107
- edit: Schema.number,
108
- hash: Schema.number,
109
- children: nodeSchema(value).mutableArray,
110
- modify: Schema.any,
111
- }),
112
- );
113
- }
114
-
115
- function indexedNodeSchema<A>(value: Schema<A>): Schema<IndexedNode<A>> {
116
- return Schema.lazy(() =>
117
- Schema.struct({
118
- _tag: Schema.literal("IndexedNode"),
119
- edit: Schema.number,
120
- mask: Schema.number,
121
- children: nodeSchema(value).mutableArray,
122
- modify: Schema.any,
123
- }),
124
- );
125
- }
126
-
127
- function arrayNodeSchema<A>(value: Schema<A>): Schema<ArrayNode<A>> {
128
- return Schema.lazy(() =>
129
- Schema.struct({
130
- _tag: Schema.literal("ArrayNode"),
131
- edit: Schema.number,
132
- size: Schema.number,
133
- children: nodeSchema(value).mutableArray,
134
- modify: Schema.any,
135
- }),
136
- );
137
- }
138
-
139
- function nodeSchema<A>(value: Schema<A>): Schema<Node<A>> {
140
- return Schema.union(
141
- emptyNodeSchema(value),
142
- leafNodeSchema(value),
143
- collisionNodeSchema(value),
144
- indexedNodeSchema(value),
145
- arrayNodeSchema(value),
146
- );
147
- }
148
-
149
- function inline<A>(value: Schema<A>): Schema<HashSet<A>> {
150
- return Schema.struct({
151
- [HashSetTypeId]: Schema.uniqueSymbol(HashSetTypeId),
152
- [HashSetVariance]: Schema.any,
153
- _editable: Schema.boolean,
154
- _edit: Schema.number,
155
- config: Schema.any,
156
- _root: nodeSchema(value),
157
- _size: Schema.number,
158
- size: Schema.number,
159
- [Symbol.iterator]: Schema.any,
160
- [Symbol.hash]: Schema.any,
161
- [Symbol.equals]: Schema.any,
162
- });
57
+ const allErrors = options?.allErrors;
58
+ const errors = Vector.emptyPushable<KeyError>();
59
+ const out = HashSet.empty<unknown>().beginMutation;
60
+ for (const v of u) {
61
+ const tv = parseValue(v, options);
62
+ Either.concrete(tv);
63
+ if (tv.isLeft()) {
64
+ errors.push(ParseError.KeyError(value.ast, value, tv.left));
65
+ if (!allErrors) {
66
+ return ParseResult.fail(ParseError.IterableError(schema.ast, u, errors));
67
+ }
68
+ continue;
69
+ }
70
+ out.add(tv.right);
71
+ }
72
+ return errors.isNonEmpty()
73
+ ? ParseResult.fail(ParseError.IterableError(schema.ast, u, errors))
74
+ : ParseResult.succeed(out.endMutation);
75
+ });
76
+ };
163
77
  }
164
78
 
165
79
  function gen<A>(value: Gen<Sized, A>): Gen<Sized, HashSet<A>> {
@@ -1,10 +1,6 @@
1
1
  import type { Sized } from "@fncts/test/control/Sized";
2
2
 
3
- import {
4
- ImmutableArray,
5
- ImmutableArrayTypeId,
6
- ImmutableArrayVariance,
7
- } from "@fncts/base/collection/immutable/ImmutableArray";
3
+ import { ImmutableArray } from "@fncts/base/collection/immutable/ImmutableArray";
8
4
  import { Vector } from "@fncts/base/collection/immutable/Vector";
9
5
 
10
6
  /**
@@ -12,12 +8,9 @@ import { Vector } from "@fncts/base/collection/immutable/Vector";
12
8
  * @tsplus static fncts.schema.SchemaOps immutableArray
13
9
  */
14
10
  export function immutableArray<A>(value: Schema<A>): Schema<ImmutableArray<A>> {
15
- return Schema.declaration(
16
- Vector(value),
17
- inline(value),
18
- parser,
19
- ASTAnnotationMap.empty.annotate(ASTAnnotation.Identifier, "ImmutableArray").annotate(ASTAnnotation.GenHook, gen),
20
- );
11
+ return Schema.declaration(Vector(value), parser(true), parser(false))
12
+ .annotate(ASTAnnotation.Identifier, `ImmutableArray<${value.show()}>`)
13
+ .annotate(ASTAnnotation.GenHook, gen);
21
14
  }
22
15
 
23
16
  /**
@@ -45,42 +38,19 @@ export function deriveImmutableArray<A extends ImmutableArray<any>>(
45
38
  return unsafeCoerce(immutableArrayFromArray(value));
46
39
  }
47
40
 
48
- function parser<A>(value: Schema<A>): Parser<ImmutableArray<A>> {
49
- const schema = immutableArray(value);
50
- return Parser.make((u, options) => {
51
- if (!ImmutableArray.is(u)) {
52
- return ParseResult.fail(ParseError.TypeError(schema.ast, u));
53
- }
54
- const out: Array<A> = [];
55
- const errors = Vector.emptyPushable<ParseError>();
56
- const allErrors = options?.allErrors;
57
- const index = 0;
58
- for (const v of u) {
59
- const t = value.decode(v, options);
60
- Either.concrete(t);
61
- if (t.isLeft()) {
62
- errors.push(ParseError.IndexError(index, t.left.errors));
63
- if (allErrors) {
64
- continue;
65
- }
66
- return ParseResult.failures(errors);
67
- } else {
68
- out.push(t.right);
41
+ function parser(isDecoding: boolean) {
42
+ return <A>(value: Schema<A>): Parser<ImmutableArray<unknown>> => {
43
+ const schema = immutableArray(value);
44
+ const arraySchema = value.array;
45
+ const parse = isDecoding ? arraySchema.decode : arraySchema.encode;
46
+ return Parser.make((u, options) => {
47
+ if (!ImmutableArray.is(u)) {
48
+ return ParseResult.fail(ParseError.TypeError(schema.ast, u));
69
49
  }
70
- }
71
- return errors.isNonEmpty() ? ParseResult.failures(errors) : ParseResult.succeed(new ImmutableArray(out));
72
- });
73
- }
74
50
 
75
- function inline<A>(value: Schema<A>): Schema<ImmutableArray<A>> {
76
- return Schema.struct({
77
- [ImmutableArrayTypeId]: Schema.uniqueSymbol(ImmutableArrayTypeId),
78
- [ImmutableArrayVariance]: Schema.any,
79
- _array: Schema.array(value),
80
- [Symbol.equals]: Schema.any,
81
- [Symbol.hash]: Schema.any,
82
- [Symbol.iterator]: Schema.any,
83
- });
51
+ return parse(u, options).map((out) => new ImmutableArray(out as Array<unknown>));
52
+ });
53
+ };
84
54
  }
85
55
 
86
56
  function gen<A>(value: Gen<Sized, A>): Gen<Sized, ImmutableArray<A>> {
@@ -1,18 +1,14 @@
1
+ import type { IndexError } from "@fncts/schema/ParseError";
1
2
  import type { Sized } from "@fncts/test/control/Sized";
2
3
 
3
- import { ListTypeId } from "@fncts/base/collection/immutable/List";
4
-
5
4
  /**
6
5
  * @tsplus static fncts.schema.SchemaOps list
7
6
  * @tsplus getter fncts.Schema.Schema list
8
7
  */
9
8
  export function list<A>(value: Schema<A>): Schema<List<A>> {
10
- return Schema.declaration(
11
- Vector(value),
12
- inline(value),
13
- parser,
14
- ASTAnnotationMap.empty.annotate(ASTAnnotation.Identifier, "List").annotate(ASTAnnotation.GenHook, gen),
15
- );
9
+ return Schema.declaration(Vector(value), parser(true), parser(false))
10
+ .annotate(ASTAnnotation.Identifier, `List<${value.show()}>`)
11
+ .annotate(ASTAnnotation.GenHook, gen);
16
12
  }
17
13
 
18
14
  /**
@@ -40,55 +36,36 @@ export function deriveList<A extends List<any>>(
40
36
  return unsafeCoerce(listFromArray(value));
41
37
  }
42
38
 
43
- function parser<A>(value: Schema<A>): Parser<List<A>> {
44
- const schema = list(value);
45
- return Parser.make((u, options) => {
46
- if (!List.is(u)) {
47
- return ParseResult.fail(ParseError.TypeError(schema.ast, u));
48
- }
49
- const out = new ListBuffer<A>();
50
- const errors = Vector.emptyPushable<ParseError>();
51
- const allErrors = options?.allErrors;
52
- const index = 0;
53
- for (const v of u) {
54
- const t = value.decode(v, options);
55
- Either.concrete(t);
56
- if (t.isLeft()) {
57
- errors.push(ParseError.IndexError(index, t.left.errors));
58
- if (allErrors) {
59
- continue;
39
+ function parser(isDecoding: boolean) {
40
+ return <A>(value: Schema<A>): Parser<List<unknown>> => {
41
+ const schema = list(value);
42
+ const parseValue = isDecoding ? value.decode : value.encode;
43
+ return Parser.make((u, options) => {
44
+ if (!List.is(u)) {
45
+ return ParseResult.fail(ParseError.TypeError(schema.ast, u));
46
+ }
47
+ const out = new ListBuffer<unknown>();
48
+ const errors = Vector.emptyPushable<IndexError>();
49
+ const allErrors = options?.allErrors;
50
+ const index = 0;
51
+ for (const v of u) {
52
+ const t = parseValue(v, options);
53
+ Either.concrete(t);
54
+ if (t.isLeft()) {
55
+ errors.push(ParseError.IndexError(index, t.left));
56
+ if (allErrors) {
57
+ continue;
58
+ }
59
+ return ParseResult.fail(ParseError.IterableError(schema.ast, u, errors));
60
+ } else {
61
+ out.append(t.right);
60
62
  }
61
- return ParseResult.failures(errors);
62
- } else {
63
- out.append(t.right);
64
63
  }
65
- }
66
- return errors.isNonEmpty() ? ParseResult.failures(errors) : ParseResult.succeed(out.toList);
67
- });
68
- }
69
-
70
- function nil<A>(_value: Schema<A>): Schema<Nil<A>> {
71
- return Schema.struct({
72
- _tag: Schema.literal("Nil"),
73
- [ListTypeId]: Schema.uniqueSymbol(ListTypeId),
74
- [Symbol.iterator]: Schema.any,
75
- });
76
- }
77
-
78
- function cons<A>(value: Schema<A>): Schema<Cons<A>> {
79
- return Schema.lazy(() =>
80
- Schema.struct({
81
- _tag: Schema.literal("Cons"),
82
- [ListTypeId]: Schema.uniqueSymbol(ListTypeId),
83
- [Symbol.iterator]: Schema.any,
84
- head: value,
85
- tail: inline(value),
86
- }),
87
- );
88
- }
89
-
90
- function inline<A>(value: Schema<A>): Schema<List<A>> {
91
- return Schema.lazy(() => Schema.union(nil(value), cons(value)));
64
+ return errors.isNonEmpty()
65
+ ? ParseResult.fail(ParseError.IterableError(schema.ast, u, errors))
66
+ : ParseResult.succeed(out.toList);
67
+ });
68
+ };
92
69
  }
93
70
 
94
71
  function gen<A>(value: Gen<Sized, A>): Gen<Sized, List<A>> {
@@ -0,0 +1,93 @@
1
+ import type { KeyError } from "@fncts/schema/ParseError";
2
+ import type { Sized } from "@fncts/test/control/Sized";
3
+
4
+ /**
5
+ * @tsplus static fncts.schema.SchemaOps map
6
+ */
7
+ export function map<K, V>(key: Schema<K>, value: Schema<V>): Schema<Map<K, V>> {
8
+ return Schema.declaration(Vector(key, value), mapParser(true), mapParser(false))
9
+ .annotate(ASTAnnotation.Identifier, `Map<${key.show()}, ${value.show()}>`)
10
+ .annotate(ASTAnnotation.GenHook, gen);
11
+ }
12
+
13
+ /**
14
+ * @tsplus static fncts.schema.SchemaOps mapFromRecord
15
+ */
16
+ export function mapFromRecord<K extends string | symbol, V>(key: Schema<K>, value: Schema<V>): Schema<Map<K, V>> {
17
+ return Schema.record(key, value).transform(
18
+ map(key, value),
19
+ (input) => {
20
+ const out = new Map<K, V>();
21
+ for (const [k, v] of Object.entries(input)) {
22
+ out.set(k as K, v as V);
23
+ }
24
+ return out;
25
+ },
26
+ (input) => {
27
+ const out = {} as Record<K, V>;
28
+ input.forEach((v, k) => {
29
+ out[k] = v;
30
+ });
31
+ return out;
32
+ },
33
+ );
34
+ }
35
+
36
+ /**
37
+ * @tsplus derive fncts.schema.Schema[fncts.Map]<_> 10
38
+ */
39
+ export function deriveMap<A extends Map<any, any>>(
40
+ // @ts-expect-error
41
+ ...[key, value]: [A] extends [Map<infer K, infer V>]
42
+ ? Check<Check.IsEqual<A, Map<K, V>> & Check.Extends<K, string | symbol>> extends Check.True
43
+ ? [key: Schema<K>, value: Schema<V>]
44
+ : never
45
+ : never
46
+ ): Schema<A> {
47
+ return unsafeCoerce(mapFromRecord(key as Schema<string | symbol>, value));
48
+ }
49
+
50
+ function mapParser(isDecoding: boolean) {
51
+ return <K, V>(key: Schema<K>, value: Schema<V>): Parser<Map<unknown, unknown>> => {
52
+ const schema = map(key, value);
53
+ return Parser.make((u, options) => {
54
+ if (!(u instanceof Map)) {
55
+ return ParseResult.fail(ParseError.TypeError(schema.ast, u));
56
+ }
57
+ const allErrors = options?.allErrors;
58
+ const errors = Vector.emptyPushable<KeyError>();
59
+ const out = new Map();
60
+ const keyParser = isDecoding ? key.decode : key.encode;
61
+ const valueParser = isDecoding ? value.decode : value.encode;
62
+ for (const [k, v] of u) {
63
+ const tk = keyParser(k, options);
64
+ Either.concrete(tk);
65
+ if (tk.isLeft()) {
66
+ errors.push(ParseError.KeyError(key.ast, k, tk.left));
67
+ if (!allErrors) {
68
+ return ParseResult.fail(ParseError.IterableError(schema.ast, u, errors));
69
+ }
70
+ }
71
+ const tv = valueParser(v, options);
72
+ Either.concrete(tv);
73
+ if (tv.isLeft()) {
74
+ errors.push(ParseError.KeyError(key.ast, k, ParseError.TypeError(value.ast, tv.left)));
75
+ if (!allErrors) {
76
+ return ParseResult.fail(ParseError.IterableError(schema.ast, u, errors));
77
+ }
78
+ }
79
+ if (tk.isLeft() || tv.isLeft()) {
80
+ continue;
81
+ }
82
+ out.set(tk.right, tv.right);
83
+ }
84
+ return errors.isNonEmpty()
85
+ ? ParseResult.fail(ParseError.IterableError(schema.ast, u, errors))
86
+ : ParseResult.succeed(out);
87
+ });
88
+ };
89
+ }
90
+
91
+ function gen<K, V>(key: Gen<Sized, K>, value: Gen<Sized, V>): Gen<Sized, Map<K, V>> {
92
+ return Gen.array(Gen.tuple(key, value)).map((pairs) => new Map(pairs));
93
+ }