add ClassMap data structure
This commit is contained in:
parent
57e3126702
commit
69494ebd28
2 changed files with 66 additions and 0 deletions
|
@ -25,3 +25,4 @@ export { Channel } from "./lib/Channel.ts";
|
|||
export { Range, range } from "./lib/Range.ts";
|
||||
export { Event } from "./lib/Event.ts";
|
||||
export { AsyncPool } from "./lib/AsyncPool.ts";
|
||||
export { ClassMap } from "./lib/ClassMap.ts";
|
||||
|
|
65
src/lib/ClassMap.ts
Normal file
65
src/lib/ClassMap.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
import { assert } from "https://deno.land/std@0.224.0/assert/assert.ts";
|
||||
import { assertInstanceOf } from "https://deno.land/std@0.224.0/assert/assert_instance_of.ts";
|
||||
|
||||
export type Prototyped<P = unknown> = { constructor: { prototype: P } };
|
||||
// deno-lint-ignore no-explicit-any
|
||||
export type Constructible<I = unknown> = new (...args: any[]) => I;
|
||||
export class ClassMap<B = unknown> {
|
||||
private inner;
|
||||
|
||||
constructor() {
|
||||
this.inner = new Map();
|
||||
}
|
||||
|
||||
insert<V extends Prototyped & B>(object: V) {
|
||||
const prototype = object.constructor.prototype;
|
||||
if (this.inner.has(prototype)) throw new Error();
|
||||
this.inner.set(prototype, object);
|
||||
}
|
||||
|
||||
get<I extends B, C extends Constructible<I>>(class_: C) {
|
||||
const value = this.inner.get(class_.prototype);
|
||||
if (value === undefined) return null;
|
||||
assertInstanceOf(value, class_);
|
||||
return value;
|
||||
}
|
||||
|
||||
has<I extends B, C extends Constructible<I>>(class_: C) {
|
||||
return this.inner.has(class_.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
Deno.test("test_classmap", () => {
|
||||
{
|
||||
class Truc {}
|
||||
class Machin {}
|
||||
class Chose {}
|
||||
|
||||
const map = new ClassMap();
|
||||
const truc = new Truc();
|
||||
map.insert(truc);
|
||||
const machin = new Machin();
|
||||
map.insert(machin);
|
||||
|
||||
assert(map.get(Truc) === truc);
|
||||
assert(map.get(Machin) !== truc);
|
||||
assert(map.get(Machin) === machin);
|
||||
assert(map.get(Chose) === null);
|
||||
}
|
||||
{
|
||||
interface Machinable {
|
||||
machin(): number;
|
||||
}
|
||||
// deno-lint-ignore no-unused-vars
|
||||
class Truc {}
|
||||
class Machin implements Machinable {
|
||||
machin = () => 35;
|
||||
}
|
||||
const map = new ClassMap<Machinable>();
|
||||
map.insert(new Machin());
|
||||
// map.insert(new Truc()); // note : Fails with improper typing.
|
||||
|
||||
map.get(Machin);
|
||||
// map.get(Truc); // note : Fails with improper typing.
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue