-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathserialize_property_options_map.ts
More file actions
137 lines (125 loc) · 4.68 KB
/
serialize_property_options_map.ts
File metadata and controls
137 lines (125 loc) · 4.68 KB
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
137
// Copyright 2018-2025 Gamebridge.ai authors. All rights reserved. MIT license.
import { SerializePropertyOptions } from "./serialize_property.ts";
import {
ERROR_DUPLICATE_PROPERTY_KEY,
ERROR_DUPLICATE_SERIALIZE_KEY,
} from "./error_messages.ts";
/** Double indexed map of Serialized Property Options
* The property options of a Serialize Property can be looked up by both the
* property key on the original object, and the serialized property key used
* in json
*
* When adding a key to the map that overlaps the property key or the serialize
* key of a parent key any parent entries using those keys will be ignored, even
* if no entry for the child map exists
*/
export class SerializePropertyOptionsMap {
private propertyKeyMap = new Map<string | symbol, SerializePropertyOptions>();
private serializedKeyMap = new Map<string, SerializePropertyOptions>();
// Set of serialized keys to ignore. This is to hide serialized keys on the parent
// when a different property key is overridden for the same serialized key
private propertyKeyIgnoreSet = new Set<string | symbol>();
private serializedKeyIgnoreSet = new Set<string>();
constructor(private parentMap?: SerializePropertyOptionsMap) {}
/** Setting a key will throw an error if there are key collisions with either
* an existing property key or serialized key
*/
public set(serializePropertyOptions: SerializePropertyOptions): void {
if (this.serializedKeyMap.has(serializePropertyOptions.serializedKey)) {
throw new Error(
`${ERROR_DUPLICATE_SERIALIZE_KEY}: ${serializePropertyOptions.serializedKey}`,
);
}
if (this.propertyKeyMap.has(serializePropertyOptions.propertyKey)) {
throw new Error(
`${ERROR_DUPLICATE_PROPERTY_KEY}: ${serializePropertyOptions.propertyKey.toString()}`,
);
}
this.propertyKeyIgnoreSet.delete(serializePropertyOptions.propertyKey);
this.propertyKeyMap.set(
serializePropertyOptions.propertyKey,
serializePropertyOptions,
);
this.serializedKeyIgnoreSet.delete(serializePropertyOptions.serializedKey);
this.serializedKeyMap.set(
serializePropertyOptions.serializedKey,
serializePropertyOptions,
);
// Hide parent property key mappings for previous value of serialized key
const parentSerializedObject = this.parentMap?.getBySerializedKey(
serializePropertyOptions.serializedKey,
);
if (
parentSerializedObject &&
parentSerializedObject.propertyKey !==
serializePropertyOptions.propertyKey
) {
this.propertyKeyIgnoreSet.add(parentSerializedObject.propertyKey);
}
// Hide parent serializedKey mapping for previous value of property key
const parentPropertyObject = this.parentMap?.getByPropertyKey(
serializePropertyOptions.propertyKey,
);
if (
parentPropertyObject &&
parentPropertyObject.serializedKey !==
serializePropertyOptions.serializedKey
) {
this.serializedKeyIgnoreSet.add(parentPropertyObject.serializedKey);
}
}
public hasPropertyKey(propertyKey: string | symbol): boolean {
return (
this.propertyKeyMap.has(propertyKey) ||
(!this.propertyKeyIgnoreSet.has(propertyKey) &&
this.parentMap?.hasPropertyKey(propertyKey)) ||
false
);
}
public getByPropertyKey(
propertyKey: string | symbol,
): SerializePropertyOptions | undefined {
return (
this.propertyKeyMap.get(propertyKey) ||
(!this.propertyKeyIgnoreSet.has(propertyKey) &&
this.parentMap?.getByPropertyKey(propertyKey)) ||
undefined
);
}
public hasSerializedKey(serializedKey: string): boolean {
return (
this.serializedKeyMap.has(serializedKey) ||
(!this.serializedKeyIgnoreSet.has(serializedKey) &&
this.parentMap?.hasSerializedKey(serializedKey)) ||
false
);
}
public getBySerializedKey(
serializedKey: string,
): SerializePropertyOptions | undefined {
return (
this.serializedKeyMap.get(serializedKey) ||
(!this.serializedKeyIgnoreSet.has(serializedKey) &&
this.parentMap?.getBySerializedKey(serializedKey)) ||
undefined
);
}
/** Get a map of all property entries for this map,
* including parent entires, excluding any ignored parent properties
*/
private getMergedWithParentMap(): Map<
string | symbol,
SerializePropertyOptions
> {
const parentEntries = Array.from(
this.parentMap?.getMergedWithParentMap() || [],
);
return new Map([
...parentEntries.filter((e) => !this.propertyKeyIgnoreSet.has(e[0])),
...this.propertyKeyMap,
]);
}
public propertyOptions(): Iterable<SerializePropertyOptions> {
return this.getMergedWithParentMap().values();
}
}