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 { Range, range } from "./lib/Range.ts";
|
||||||
export { Event } from "./lib/Event.ts";
|
export { Event } from "./lib/Event.ts";
|
||||||
export { AsyncPool } from "./lib/AsyncPool.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