macroforge 0.1.29 → 0.1.31

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.
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Trait interfaces for macroforge derive macros.
3
+ * All members are readonly and use function-style signatures (for namespace compatibility).
4
+ */
5
+
6
+ // Clone trait - deep copy capability
7
+ export interface Clone<T> {
8
+ readonly clone: (self: T) => T;
9
+ }
10
+
11
+ // Debug trait - string representation for debugging
12
+ export interface Debug<T> {
13
+ readonly toString: (self: T) => string;
14
+ }
15
+
16
+ // Default trait - factory for default values
17
+ export interface Default<T> {
18
+ readonly defaultValue: () => T;
19
+ }
20
+
21
+ // PartialEq trait - equality comparison
22
+ export interface PartialEq<T> {
23
+ readonly equals: (self: T, other: unknown) => boolean;
24
+ }
25
+
26
+ // Hash trait - hash code generation
27
+ export interface Hash<T> {
28
+ readonly hashCode: (self: T) => number;
29
+ }
30
+
31
+ // PartialOrd trait - partial ordering (may return null for incomparable values)
32
+ export interface PartialOrd<T> {
33
+ readonly compareTo: (self: T, other: unknown) => number | null;
34
+ }
35
+
36
+ // Ord trait - total ordering (always returns a number)
37
+ export interface Ord<T> {
38
+ readonly compareTo: (self: T, other: T) => number;
39
+ }
40
+
41
+ // Serialize trait - convert to JSON
42
+ export interface Serialize<T> {
43
+ readonly toStringifiedJSON: (self: T) => string;
44
+ readonly toObject: (self: T) => Record<string, unknown>;
45
+ }
46
+
47
+ // Deserialize trait - construct from JSON or object
48
+ export interface Deserialize<T> {
49
+ readonly fromStringifiedJSON: (json: string) => T;
50
+ readonly fromObject: (obj: unknown) => T;
51
+ }
@@ -0,0 +1,308 @@
1
+ export { Result, Option } from "@rydshift/mirror/declarative";
2
+ /**
3
+ *
4
+ *
5
+ * // Option types
6
+
7
+ export interface Some<T> {
8
+ readonly tag: "Some";
9
+ readonly value: T;
10
+ }
11
+
12
+ export interface None {
13
+ readonly tag: "None";
14
+ }
15
+
16
+ export type Option<T> = Some<T> | None;
17
+
18
+ export namespace Option {
19
+ export function some<T>(value: T): Option<T> {
20
+ return { tag: "Some", value };
21
+ }
22
+
23
+ export function none<T>(): Option<T> {
24
+ return { tag: "None" };
25
+ }
26
+
27
+ export function isSome<T>(opt: Option<T>): opt is Some<T> {
28
+ return opt.tag === "Some";
29
+ }
30
+
31
+ export function isNone<T>(opt: Option<T>): opt is None {
32
+ return opt.tag === "None";
33
+ }
34
+
35
+ export function isSomeAnd<T>(opt: Option<T>, f: (value: T) => boolean): boolean {
36
+ return isSome(opt) && f(opt.value);
37
+ }
38
+
39
+ export function isNoneOr<T>(opt: Option<T>, f: (value: T) => boolean): boolean {
40
+ return isNone(opt) || f(opt.value);
41
+ }
42
+
43
+ export function expect<T>(opt: Option<T>, msg: string): T {
44
+ if (isSome(opt)) return opt.value;
45
+ throw new Error(msg);
46
+ }
47
+
48
+ export function unwrap<T>(opt: Option<T>): T {
49
+ if (isSome(opt)) return opt.value;
50
+ throw new Error("called `Option::unwrap()` on a `None` value");
51
+ }
52
+
53
+ export function unwrapOr<T>(opt: Option<T>, defaultValue: T): T {
54
+ return isSome(opt) ? opt.value : defaultValue;
55
+ }
56
+
57
+ export function unwrapOrElse<T>(opt: Option<T>, f: () => T): T {
58
+ return isSome(opt) ? opt.value : f();
59
+ }
60
+
61
+ export function unwrapOrDefault<T>(opt: Option<T>): T {
62
+ return isSome(opt) ? opt.value : ("" as unknown as T);
63
+ }
64
+
65
+ export function map<T, U>(opt: Option<T>, f: (value: T) => U): Option<U> {
66
+ return isSome(opt) ? some(f(opt.value)) : none();
67
+ }
68
+
69
+ export function mapOr<T, U>(opt: Option<T>, defaultValue: U, f: (value: T) => U): U {
70
+ return isSome(opt) ? f(opt.value) : defaultValue;
71
+ }
72
+
73
+ export function mapOrElse<T, U>(opt: Option<T>, defaultFn: () => U, f: (value: T) => U): U {
74
+ return isSome(opt) ? f(opt.value) : defaultFn();
75
+ }
76
+
77
+ export function inspect<T>(opt: Option<T>, f: (value: T) => void): Option<T> {
78
+ if (isSome(opt)) f(opt.value);
79
+ return opt;
80
+ }
81
+
82
+ export function okOr<T, E>(opt: Option<T>, err: E): Result<T, E> {
83
+ return isSome(opt) ? Result.ok(opt.value) : Result.err(err);
84
+ }
85
+
86
+ export function okOrElse<T, E>(opt: Option<T>, errFn: () => E): Result<T, E> {
87
+ return isSome(opt) ? Result.ok(opt.value) : Result.err(errFn());
88
+ }
89
+
90
+ export function and<T, U>(opt: Option<T>, other: Option<U>): Option<U> {
91
+ return isSome(opt) ? other : none();
92
+ }
93
+
94
+ export function andThen<T, U>(opt: Option<T>, f: (value: T) => Option<U>): Option<U> {
95
+ return isSome(opt) ? f(opt.value) : none();
96
+ }
97
+
98
+ export function or<T>(opt: Option<T>, other: Option<T>): Option<T> {
99
+ return isSome(opt) ? opt : other;
100
+ }
101
+
102
+ export function orElse<T>(opt: Option<T>, f: () => Option<T>): Option<T> {
103
+ return isSome(opt) ? opt : f();
104
+ }
105
+
106
+ export function filter<T>(opt: Option<T>, predicate: (value: T) => boolean): Option<T> {
107
+ return isSome(opt) && predicate(opt.value) ? opt : none();
108
+ }
109
+
110
+ export function xor<T>(opt: Option<T>, other: Option<T>): Option<T> {
111
+ if (isSome(opt) && isNone(other)) return opt;
112
+ if (isNone(opt) && isSome(other)) return other;
113
+ return none();
114
+ }
115
+
116
+ export function zip<T, U>(opt: Option<T>, other: Option<U>): Option<[T, U]> {
117
+ return isSome(opt) && isSome(other) ? some([opt.value, other.value]) : none();
118
+ }
119
+
120
+ export function zipWith<T, U, R>(opt: Option<T>, other: Option<U>, f: (a: T, b: U) => R): Option<R> {
121
+ return isSome(opt) && isSome(other) ? some(f(opt.value, other.value)) : none();
122
+ }
123
+
124
+ export function flatten<T>(opt: Option<Option<T>>): Option<T> {
125
+ return isSome(opt) ? opt.value : none();
126
+ }
127
+
128
+ export function transpose<T, E>(opt: Option<Result<T, E>>): Result<Option<T>, E> {
129
+ if (isNone(opt)) return Result.ok(none());
130
+ if (Result.isOk(opt.value)) return Result.ok(some(opt.value.value));
131
+ return Result.err(opt.value.error);
132
+ }
133
+
134
+ export function match<T, U>(opt: Option<T>, onSome: (value: T) => U, onNone: () => U): U {
135
+ return isSome(opt) ? onSome(opt.value) : onNone();
136
+ }
137
+ }
138
+
139
+ // Result types
140
+
141
+ export interface Ok<T> {
142
+ readonly tag: "Ok";
143
+ readonly value: T;
144
+ }
145
+
146
+ export interface Err<E> {
147
+ readonly tag: "Err";
148
+ readonly error: E;
149
+ }
150
+
151
+ export type Result<T, E> = Ok<T> | Err<E>;
152
+
153
+ export namespace Result {
154
+ export function ok<T, E = never>(value: T): Result<T, E> {
155
+ return { tag: "Ok", value };
156
+ }
157
+
158
+ export function err<T = never, E = unknown>(error: E): Result<T, E> {
159
+ return { tag: "Err", error };
160
+ }
161
+
162
+ export function isOk<T, E>(res: Result<T, E>): res is Ok<T> {
163
+ return res.tag === "Ok";
164
+ }
165
+
166
+ export function isErr<T, E>(res: Result<T, E>): res is Err<E> {
167
+ return res.tag === "Err";
168
+ }
169
+
170
+ export function isOkAnd<T, E>(res: Result<T, E>, f: (value: T) => boolean): boolean {
171
+ return isOk(res) && f(res.value);
172
+ }
173
+
174
+ export function isErrAnd<T, E>(res: Result<T, E>, f: (error: E) => boolean): boolean {
175
+ return isErr(res) && f(res.error);
176
+ }
177
+
178
+ export function toOk<T, E>(res: Result<T, E>): Option<T> {
179
+ return isOk(res) ? Option.some(res.value) : Option.none();
180
+ }
181
+
182
+ export function toErr<T, E>(res: Result<T, E>): Option<E> {
183
+ return isErr(res) ? Option.some(res.error) : Option.none();
184
+ }
185
+
186
+ export function expect<T, E>(res: Result<T, E>, msg: string): T {
187
+ if (isOk(res)) return res.value;
188
+ throw new Error(`${msg}: ${res.error}`);
189
+ }
190
+
191
+ export function expectErr<T, E>(res: Result<T, E>, msg: string): E {
192
+ if (isErr(res)) return res.error;
193
+ throw new Error(`${msg}: ${res.value}`);
194
+ }
195
+
196
+ export function unwrap<T, E>(res: Result<T, E>): T {
197
+ if (isOk(res)) return res.value;
198
+ throw new Error(`called \`Result::unwrap()\` on an \`Err\` value: ${(res as Err<E>).error}`);
199
+ }
200
+
201
+ export function unwrapErr<T, E>(res: Result<T, E>): E {
202
+ if (isErr(res)) return res.error;
203
+ throw new Error(`called \`Result::unwrap_err()\` on an \`Ok\` value: ${(res as Ok<T>).value}`);
204
+ }
205
+
206
+ export function unwrapOr<T, E>(res: Result<T, E>, defaultValue: T): T {
207
+ return isOk(res) ? res.value : defaultValue;
208
+ }
209
+
210
+ export function unwrapOrElse<T, E>(res: Result<T, E>, f: (error: E) => T): T {
211
+ return isOk(res) ? res.value : f(res.error);
212
+ }
213
+
214
+ export function unwrapOrDefault<T, E>(res: Result<T, E>): T {
215
+ return isOk(res) ? res.value : ("" as unknown as T);
216
+ }
217
+
218
+ export function map<T, U, E>(res: Result<T, E>, f: (value: T) => U): Result<U, E> {
219
+ return isOk(res) ? ok(f(res.value)) : err(res.error);
220
+ }
221
+
222
+ export function mapOr<T, U, E>(res: Result<T, E>, defaultValue: U, f: (value: T) => U): U {
223
+ return isOk(res) ? f(res.value) : defaultValue;
224
+ }
225
+
226
+ export function mapOrElse<T, U, E>(res: Result<T, E>, defaultFn: (error: E) => U, f: (value: T) => U): U {
227
+ return isOk(res) ? f(res.value) : defaultFn(res.error);
228
+ }
229
+
230
+ export function mapErr<T, E, F>(res: Result<T, E>, f: (error: E) => F): Result<T, F> {
231
+ return isOk(res) ? ok(res.value) : err(f(res.error));
232
+ }
233
+
234
+ export function inspect<T, E>(res: Result<T, E>, f: (value: T) => void): Result<T, E> {
235
+ if (isOk(res)) f(res.value);
236
+ return res;
237
+ }
238
+
239
+ export function inspectErr<T, E>(res: Result<T, E>, f: (error: E) => void): Result<T, E> {
240
+ if (isErr(res)) f(res.error);
241
+ return res;
242
+ }
243
+
244
+ export function and<T, U, E>(res: Result<T, E>, other: Result<U, E>): Result<U, E> {
245
+ return isOk(res) ? other : err(res.error);
246
+ }
247
+
248
+ export function andThen<T, U, E>(res: Result<T, E>, f: (value: T) => Result<U, E>): Result<U, E> {
249
+ return isOk(res) ? f(res.value) : err(res.error);
250
+ }
251
+
252
+ export function or<T, E, F>(res: Result<T, E>, other: Result<T, F>): Result<T, F> {
253
+ return isOk(res) ? ok(res.value) : other;
254
+ }
255
+
256
+ export function orElse<T, E, F>(res: Result<T, E>, f: (error: E) => Result<T, F>): Result<T, F> {
257
+ return isOk(res) ? ok(res.value) : f(res.error);
258
+ }
259
+
260
+ export function flatten<T, E>(res: Result<Result<T, E>, E>): Result<T, E> {
261
+ return isOk(res) ? res.value : err(res.error);
262
+ }
263
+
264
+ export function transpose<T, E>(res: Result<Option<T>, E>): Option<Result<T, E>> {
265
+ if (isErr(res)) return Option.some(err(res.error));
266
+ if (Option.isNone(res.value)) return Option.none();
267
+ return Option.some(ok(res.value.value));
268
+ }
269
+
270
+ export function match<T, E, U>(res: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => U): U {
271
+ return isOk(res) ? onOk(res.value) : onErr(res.error);
272
+ }
273
+ }
274
+
275
+ // ThisError
276
+
277
+ export interface ThisError<K extends string = string> {
278
+ readonly kind: K;
279
+ readonly message: string;
280
+ readonly source?: Error;
281
+ }
282
+
283
+ export namespace ThisError {
284
+ export function create<K extends string>(
285
+ kind: K,
286
+ message: string,
287
+ source?: Error,
288
+ ): ThisError<K> {
289
+ return { kind, message, source };
290
+ }
291
+
292
+ export function define<K extends string>(kind: K) {
293
+ return (message: string, source?: Error): ThisError<K> => ({
294
+ kind,
295
+ message,
296
+ source,
297
+ });
298
+ }
299
+
300
+ export function toError(e: ThisError): Error {
301
+ const err = new Error(e.message);
302
+ err.name = e.kind;
303
+ if (e.source) err.cause = e.source;
304
+ return err;
305
+ }
306
+ }
307
+
308
+ */
@@ -0,0 +1,6 @@
1
+ // js/utils/index.ts
2
+ import { Result, Option } from "@rydshift/mirror/declarative";
3
+ export {
4
+ Result,
5
+ Option
6
+ };
@@ -0,0 +1,310 @@
1
+ // Re-export Result and Option from @rydshift/mirror for use in generated code
2
+ export { Result, Option } from "@rydshift/mirror/declarative";
3
+
4
+ /**
5
+ *
6
+ *
7
+ * // Option types
8
+
9
+ export interface Some<T> {
10
+ readonly tag: "Some";
11
+ readonly value: T;
12
+ }
13
+
14
+ export interface None {
15
+ readonly tag: "None";
16
+ }
17
+
18
+ export type Option<T> = Some<T> | None;
19
+
20
+ export namespace Option {
21
+ export function some<T>(value: T): Option<T> {
22
+ return { tag: "Some", value };
23
+ }
24
+
25
+ export function none<T>(): Option<T> {
26
+ return { tag: "None" };
27
+ }
28
+
29
+ export function isSome<T>(opt: Option<T>): opt is Some<T> {
30
+ return opt.tag === "Some";
31
+ }
32
+
33
+ export function isNone<T>(opt: Option<T>): opt is None {
34
+ return opt.tag === "None";
35
+ }
36
+
37
+ export function isSomeAnd<T>(opt: Option<T>, f: (value: T) => boolean): boolean {
38
+ return isSome(opt) && f(opt.value);
39
+ }
40
+
41
+ export function isNoneOr<T>(opt: Option<T>, f: (value: T) => boolean): boolean {
42
+ return isNone(opt) || f(opt.value);
43
+ }
44
+
45
+ export function expect<T>(opt: Option<T>, msg: string): T {
46
+ if (isSome(opt)) return opt.value;
47
+ throw new Error(msg);
48
+ }
49
+
50
+ export function unwrap<T>(opt: Option<T>): T {
51
+ if (isSome(opt)) return opt.value;
52
+ throw new Error("called `Option::unwrap()` on a `None` value");
53
+ }
54
+
55
+ export function unwrapOr<T>(opt: Option<T>, defaultValue: T): T {
56
+ return isSome(opt) ? opt.value : defaultValue;
57
+ }
58
+
59
+ export function unwrapOrElse<T>(opt: Option<T>, f: () => T): T {
60
+ return isSome(opt) ? opt.value : f();
61
+ }
62
+
63
+ export function unwrapOrDefault<T>(opt: Option<T>): T {
64
+ return isSome(opt) ? opt.value : ("" as unknown as T);
65
+ }
66
+
67
+ export function map<T, U>(opt: Option<T>, f: (value: T) => U): Option<U> {
68
+ return isSome(opt) ? some(f(opt.value)) : none();
69
+ }
70
+
71
+ export function mapOr<T, U>(opt: Option<T>, defaultValue: U, f: (value: T) => U): U {
72
+ return isSome(opt) ? f(opt.value) : defaultValue;
73
+ }
74
+
75
+ export function mapOrElse<T, U>(opt: Option<T>, defaultFn: () => U, f: (value: T) => U): U {
76
+ return isSome(opt) ? f(opt.value) : defaultFn();
77
+ }
78
+
79
+ export function inspect<T>(opt: Option<T>, f: (value: T) => void): Option<T> {
80
+ if (isSome(opt)) f(opt.value);
81
+ return opt;
82
+ }
83
+
84
+ export function okOr<T, E>(opt: Option<T>, err: E): Result<T, E> {
85
+ return isSome(opt) ? Result.ok(opt.value) : Result.err(err);
86
+ }
87
+
88
+ export function okOrElse<T, E>(opt: Option<T>, errFn: () => E): Result<T, E> {
89
+ return isSome(opt) ? Result.ok(opt.value) : Result.err(errFn());
90
+ }
91
+
92
+ export function and<T, U>(opt: Option<T>, other: Option<U>): Option<U> {
93
+ return isSome(opt) ? other : none();
94
+ }
95
+
96
+ export function andThen<T, U>(opt: Option<T>, f: (value: T) => Option<U>): Option<U> {
97
+ return isSome(opt) ? f(opt.value) : none();
98
+ }
99
+
100
+ export function or<T>(opt: Option<T>, other: Option<T>): Option<T> {
101
+ return isSome(opt) ? opt : other;
102
+ }
103
+
104
+ export function orElse<T>(opt: Option<T>, f: () => Option<T>): Option<T> {
105
+ return isSome(opt) ? opt : f();
106
+ }
107
+
108
+ export function filter<T>(opt: Option<T>, predicate: (value: T) => boolean): Option<T> {
109
+ return isSome(opt) && predicate(opt.value) ? opt : none();
110
+ }
111
+
112
+ export function xor<T>(opt: Option<T>, other: Option<T>): Option<T> {
113
+ if (isSome(opt) && isNone(other)) return opt;
114
+ if (isNone(opt) && isSome(other)) return other;
115
+ return none();
116
+ }
117
+
118
+ export function zip<T, U>(opt: Option<T>, other: Option<U>): Option<[T, U]> {
119
+ return isSome(opt) && isSome(other) ? some([opt.value, other.value]) : none();
120
+ }
121
+
122
+ export function zipWith<T, U, R>(opt: Option<T>, other: Option<U>, f: (a: T, b: U) => R): Option<R> {
123
+ return isSome(opt) && isSome(other) ? some(f(opt.value, other.value)) : none();
124
+ }
125
+
126
+ export function flatten<T>(opt: Option<Option<T>>): Option<T> {
127
+ return isSome(opt) ? opt.value : none();
128
+ }
129
+
130
+ export function transpose<T, E>(opt: Option<Result<T, E>>): Result<Option<T>, E> {
131
+ if (isNone(opt)) return Result.ok(none());
132
+ if (Result.isOk(opt.value)) return Result.ok(some(opt.value.value));
133
+ return Result.err(opt.value.error);
134
+ }
135
+
136
+ export function match<T, U>(opt: Option<T>, onSome: (value: T) => U, onNone: () => U): U {
137
+ return isSome(opt) ? onSome(opt.value) : onNone();
138
+ }
139
+ }
140
+
141
+ // Result types
142
+
143
+ export interface Ok<T> {
144
+ readonly tag: "Ok";
145
+ readonly value: T;
146
+ }
147
+
148
+ export interface Err<E> {
149
+ readonly tag: "Err";
150
+ readonly error: E;
151
+ }
152
+
153
+ export type Result<T, E> = Ok<T> | Err<E>;
154
+
155
+ export namespace Result {
156
+ export function ok<T, E = never>(value: T): Result<T, E> {
157
+ return { tag: "Ok", value };
158
+ }
159
+
160
+ export function err<T = never, E = unknown>(error: E): Result<T, E> {
161
+ return { tag: "Err", error };
162
+ }
163
+
164
+ export function isOk<T, E>(res: Result<T, E>): res is Ok<T> {
165
+ return res.tag === "Ok";
166
+ }
167
+
168
+ export function isErr<T, E>(res: Result<T, E>): res is Err<E> {
169
+ return res.tag === "Err";
170
+ }
171
+
172
+ export function isOkAnd<T, E>(res: Result<T, E>, f: (value: T) => boolean): boolean {
173
+ return isOk(res) && f(res.value);
174
+ }
175
+
176
+ export function isErrAnd<T, E>(res: Result<T, E>, f: (error: E) => boolean): boolean {
177
+ return isErr(res) && f(res.error);
178
+ }
179
+
180
+ export function toOk<T, E>(res: Result<T, E>): Option<T> {
181
+ return isOk(res) ? Option.some(res.value) : Option.none();
182
+ }
183
+
184
+ export function toErr<T, E>(res: Result<T, E>): Option<E> {
185
+ return isErr(res) ? Option.some(res.error) : Option.none();
186
+ }
187
+
188
+ export function expect<T, E>(res: Result<T, E>, msg: string): T {
189
+ if (isOk(res)) return res.value;
190
+ throw new Error(`${msg}: ${res.error}`);
191
+ }
192
+
193
+ export function expectErr<T, E>(res: Result<T, E>, msg: string): E {
194
+ if (isErr(res)) return res.error;
195
+ throw new Error(`${msg}: ${res.value}`);
196
+ }
197
+
198
+ export function unwrap<T, E>(res: Result<T, E>): T {
199
+ if (isOk(res)) return res.value;
200
+ throw new Error(`called \`Result::unwrap()\` on an \`Err\` value: ${(res as Err<E>).error}`);
201
+ }
202
+
203
+ export function unwrapErr<T, E>(res: Result<T, E>): E {
204
+ if (isErr(res)) return res.error;
205
+ throw new Error(`called \`Result::unwrap_err()\` on an \`Ok\` value: ${(res as Ok<T>).value}`);
206
+ }
207
+
208
+ export function unwrapOr<T, E>(res: Result<T, E>, defaultValue: T): T {
209
+ return isOk(res) ? res.value : defaultValue;
210
+ }
211
+
212
+ export function unwrapOrElse<T, E>(res: Result<T, E>, f: (error: E) => T): T {
213
+ return isOk(res) ? res.value : f(res.error);
214
+ }
215
+
216
+ export function unwrapOrDefault<T, E>(res: Result<T, E>): T {
217
+ return isOk(res) ? res.value : ("" as unknown as T);
218
+ }
219
+
220
+ export function map<T, U, E>(res: Result<T, E>, f: (value: T) => U): Result<U, E> {
221
+ return isOk(res) ? ok(f(res.value)) : err(res.error);
222
+ }
223
+
224
+ export function mapOr<T, U, E>(res: Result<T, E>, defaultValue: U, f: (value: T) => U): U {
225
+ return isOk(res) ? f(res.value) : defaultValue;
226
+ }
227
+
228
+ export function mapOrElse<T, U, E>(res: Result<T, E>, defaultFn: (error: E) => U, f: (value: T) => U): U {
229
+ return isOk(res) ? f(res.value) : defaultFn(res.error);
230
+ }
231
+
232
+ export function mapErr<T, E, F>(res: Result<T, E>, f: (error: E) => F): Result<T, F> {
233
+ return isOk(res) ? ok(res.value) : err(f(res.error));
234
+ }
235
+
236
+ export function inspect<T, E>(res: Result<T, E>, f: (value: T) => void): Result<T, E> {
237
+ if (isOk(res)) f(res.value);
238
+ return res;
239
+ }
240
+
241
+ export function inspectErr<T, E>(res: Result<T, E>, f: (error: E) => void): Result<T, E> {
242
+ if (isErr(res)) f(res.error);
243
+ return res;
244
+ }
245
+
246
+ export function and<T, U, E>(res: Result<T, E>, other: Result<U, E>): Result<U, E> {
247
+ return isOk(res) ? other : err(res.error);
248
+ }
249
+
250
+ export function andThen<T, U, E>(res: Result<T, E>, f: (value: T) => Result<U, E>): Result<U, E> {
251
+ return isOk(res) ? f(res.value) : err(res.error);
252
+ }
253
+
254
+ export function or<T, E, F>(res: Result<T, E>, other: Result<T, F>): Result<T, F> {
255
+ return isOk(res) ? ok(res.value) : other;
256
+ }
257
+
258
+ export function orElse<T, E, F>(res: Result<T, E>, f: (error: E) => Result<T, F>): Result<T, F> {
259
+ return isOk(res) ? ok(res.value) : f(res.error);
260
+ }
261
+
262
+ export function flatten<T, E>(res: Result<Result<T, E>, E>): Result<T, E> {
263
+ return isOk(res) ? res.value : err(res.error);
264
+ }
265
+
266
+ export function transpose<T, E>(res: Result<Option<T>, E>): Option<Result<T, E>> {
267
+ if (isErr(res)) return Option.some(err(res.error));
268
+ if (Option.isNone(res.value)) return Option.none();
269
+ return Option.some(ok(res.value.value));
270
+ }
271
+
272
+ export function match<T, E, U>(res: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => U): U {
273
+ return isOk(res) ? onOk(res.value) : onErr(res.error);
274
+ }
275
+ }
276
+
277
+ // ThisError
278
+
279
+ export interface ThisError<K extends string = string> {
280
+ readonly kind: K;
281
+ readonly message: string;
282
+ readonly source?: Error;
283
+ }
284
+
285
+ export namespace ThisError {
286
+ export function create<K extends string>(
287
+ kind: K,
288
+ message: string,
289
+ source?: Error,
290
+ ): ThisError<K> {
291
+ return { kind, message, source };
292
+ }
293
+
294
+ export function define<K extends string>(kind: K) {
295
+ return (message: string, source?: Error): ThisError<K> => ({
296
+ kind,
297
+ message,
298
+ source,
299
+ });
300
+ }
301
+
302
+ export function toError(e: ThisError): Error {
303
+ const err = new Error(e.message);
304
+ err.name = e.kind;
305
+ if (e.source) err.cause = e.source;
306
+ return err;
307
+ }
308
+ }
309
+
310
+ */