-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathWeakOption.ts
136 lines (114 loc) · 2.71 KB
/
WeakOption.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import {Is} from './Is';
// Inspired from https://scleapt.com/typescript_option/
/**
* An interface for handling values whose existence is uncertain.
*/
const errorStr = 'The value does not exist!';
export interface IWeakOption<B extends object, T> {
unwrapOrDefault(base: B, altValue: T): T;
unwrapOrElse(base: B, f: (...vals: any) => T): T;
unwrapForce(base: B): T;
unwrapOrUndefined(base: B): T | undefined;
has(base: B): boolean;
}
export class WeakOption<B extends object, T> implements IWeakOption<B, T> {
private __weakMap: WeakMap<B, T> = new WeakMap();
set(base: B, val: T) {
this.__weakMap.set(base, val);
}
/**
* @param altValue
* @returns
*/
unwrapOrDefault(base: B, altValue: T): T {
const value = this.__weakMap.get(base);
return Is.exist(value) ? value : altValue;
}
/**
* @param altValue
* @returns
*/
unwrapOrElse(base: B, f: (...vals: any) => T): T {
const value = this.__weakMap.get(base);
return Is.exist(value) ? value : f();
}
/**
* @returns
*/
unwrapForce(base: B): T {
const value = this.__weakMap.get(base);
if (Is.exist(value)) {
return value;
} else {
throw new ReferenceError(errorStr);
}
}
unwrapOrUndefined(base: B): T | undefined {
return this.__weakMap.get(base);
}
has(base: B): boolean {
return this.__weakMap.has(base);
}
}
/**
* a class indicating that the included value exists.
*/
export class WeakSome<B extends object, T> implements IWeakOption<B, T> {
private __weakMap: WeakMap<B, T> = new WeakMap();
constructor(base: B, value: T) {
this.__weakMap.set(base, value);
}
/**
* @param altValue
* @returns
*/
unwrapOrDefault(base: B, altValue: T): T {
return this.__weakMap.get(base)!;
}
/**
* @param altValue
* @returns
*/
unwrapOrElse(base: B, f: (value: T) => T): T {
return this.__weakMap.get(base)!;
}
/**
* @param altValue
* @returns
*/
unwrapForce(base: B): T {
return this.__weakMap.get(base)!;
}
get(base: B): T {
return this.__weakMap.get(base)!;
}
unwrapOrUndefined(base: B): T | undefined {
return this.__weakMap.get(base);
}
has(base: B): true {
return true;
}
}
/**
* a class indicating no existence.
*/
export class WeakNone<B extends object> implements IWeakOption<B, never> {
then(): WeakNone<B> {
return this;
}
unwrapOrDefault<T>(base: B, value: T): T {
return value;
}
unwrapOrElse(base: B, f: (...vals: any) => never): never {
return f(undefined as never);
}
unwrapForce(base: B): never {
throw new ReferenceError(errorStr);
}
unwrapOrUndefined(base: B): never {
return undefined as never;
}
has(): false {
return false;
}
}