79 lines
1.9 KiB
JavaScript
79 lines
1.9 KiB
JavaScript
import { Item_Unresolvable } from '@efforting.tech/errors';
|
|
|
|
export class Abstract_Resolver {
|
|
resolve(item) {
|
|
const result = this.resolve_handler(item);
|
|
if (!result?.handler) {
|
|
throw new Item_Unresolvable({ resolver: this, item });
|
|
}
|
|
// TO DOC: Spreading result into the resulting context means there are some reserved keys we need to be mindful of to avoid clobbering them
|
|
return result.handler({ resolver: this, item, ...result });
|
|
}
|
|
}
|
|
|
|
export class Chained_Resolver extends Abstract_Resolver {
|
|
constructor(chain_links) {
|
|
super();
|
|
Object.assign(this, { chain_links });
|
|
}
|
|
|
|
resolve_handler(item) {
|
|
const { chain_links } = this;
|
|
for (const link of chain_links) {
|
|
const result = link.resolve_handler(item);
|
|
if (result?.handler) {
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export class Predicate_Resolver extends Abstract_Resolver {
|
|
constructor(rules=[]) {
|
|
// NOTE: Rules should be iterable as [predicate, handler] pairs
|
|
super();
|
|
Object.assign(this, { rules });
|
|
}
|
|
|
|
resolve_handler(item) {
|
|
const { rules } = this;
|
|
for (const [predicate, handler] of rules) {
|
|
const predicate_result = predicate(item);
|
|
if (predicate_result !== undefined) {
|
|
return { handler, predicate_result };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export class RegExp_Resolver extends Predicate_Resolver {
|
|
constructor(rules=[]) {
|
|
// NOTE: Rules should be iterable as [predicate, handler] pairs
|
|
super();
|
|
Object.assign(this, { rules: rules.map(([pattern, handler]) => {
|
|
|
|
const wrapped_handler = handler; //TODO
|
|
const predicate = ((str) => str.match(pattern));
|
|
|
|
return [predicate, wrapped_handler];
|
|
})});
|
|
}
|
|
|
|
|
|
}
|
|
|
|
export class Mapping_Resolver extends Abstract_Resolver {
|
|
constructor(rules=new Map(), key_function=null) {
|
|
super();
|
|
Object.assign(this, { rules, key_function });
|
|
}
|
|
|
|
resolve_handler(item) {
|
|
const { key_function, rules } = this;
|
|
const key = key_function ? key_function(item) : item;
|
|
return rules.get(key);
|
|
}
|
|
|
|
}
|
|
|