-
Notifications
You must be signed in to change notification settings - Fork 0
/
result.ts
99 lines (83 loc) · 2.41 KB
/
result.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { none, Option, Some } from './option';
class Result<E = Error, R = unknown> {
static of<E, R>(success: R) {
return new Result<E, R>(null, success);
}
static error<E, R>(error: E) {
return new Result<E, R>(error);
}
left = none as Option<E>;
right!: R;
constructor(...args: [E | null, R?]) {
if (args.length === 2) {
this.right = args[1] as R;
} else {
this.left = Some.pure(args[0] as E);
}
}
tap(f: (v: R) => void): Result<E, R> {
this.left.match(
// eslint-disable-next-line @typescript-eslint/no-empty-function
() => { }
,
() => f(this.right)
);
return this;
}
cata<T>(f: (v: R) => Result<E, T>): Result<E, T>;
cata<T>(f: (v: R) => Promise<Result<E, T>>): Promise<Result<E, T>>;
cata<T>(f: (v: R) => Result<E, T> | Promise<Result<E, T>>): Result<E, T> | Promise<Result<E, T>> {
return this.left.match(
e => Result.error(e)
,
() => f(this.right)
);
}
async await<T>(this: Result<E, Promise<T>>): Promise<Result<E, T>> {
const res = this.match(async a => {
const res = await a;
return Result.of<E, T>(res);
}, e => Promise.resolve(Result.error(e)));
return res;
}
valueOrDefault(def: R): R {
return this.match(
v => v
,
() => def
);
}
map<T>(f: (v: R) => T): Result<E, T> {
return this.left.match(
e => Result.error(e)
,
() => Result.of(f(this.right))
);
}
error<T>(fn: (v: E) => T): Result<T, R> {
return this.left.match(
err => Result.error(fn(err))
,
() => Result.of(this.right)
);
}
orElse<T>(f: (v: E) => Result<E, T>): Result<E, T> {
return this.left.match(
v => f(v)
,
() => Result.of(null as T)
);
}
match<T>(success: (v: R) => T, error: (e: E) => T): T {
return this.left.match(
err => error(err)
,
() => success(this.right)
);
}
// eslint-disable-next-line @typescript-eslint/ban-types
is(a: Function): boolean {
return this.left.match(e => e instanceof a, () => this.right instanceof a);
}
}
export { Result };