import type { TType } from './typesystem.js'; import { typesystem } from './typesystem.js'; type MatcherData = { type: Type; data: Data; }; export class Matcher { private list: MatcherData[] = []; constructor( private _match: ( type: Type, target: TType ) => boolean = typesystem.isSubtype.bind(typesystem) ) {} register(type: Type, data: Data) { this.list.push({ type, data }); } match(type: TType) { for (const t of this.list) { if (this._match(t.type, type)) { return t.data; } } return; } allMatched(type: TType): MatcherData[] { const result: MatcherData[] = []; for (const t of this.list) { if (this._match(t.type, type)) { result.push(t); } } return result; } allMatchedData(type: TType): Data[] { const result: Data[] = []; for (const t of this.list) { if (this._match(t.type, type)) { result.push(t.data); } } return result; } findData(f: (data: Data) => boolean): Data | undefined { return this.list.find(data => f(data.data))?.data; } find( f: (data: MatcherData) => boolean ): MatcherData | undefined { return this.list.find(f); } all(): MatcherData[] { return this.list; } isMatched(type: Type, target: TType) { return this._match(type, target); } }