import type { CommandRule } from './contract' /** 规则读命令时出错:记下,当它没读(命令照抄)。 */ function guarded(rule: CommandRule, report: (message: string) => void): CommandRule { return { ...rule, read: (command, context) => { try { return rule.read(command, context) } catch (err) { report(`命令规则 ${rule.id} 读「${command.name.node.text}」时出错,照抄命令:${err instanceof Error ? err.message : String(err)}`) return undefined } }, } } /** 管没有自己的规则的命令的规则写的命令名。 */ const ANY_COMMAND = '*' /** 命令名 → 命令规则(SourceDocument.commandRule):几条规则都管同一个名字时先注册的算;没有自己的规则的交给管 '*' 的。 */ export function commandRuleLookup(rules: readonly CommandRule[], report: (message: string) => void): (name: string) => CommandRule | undefined { const byName = new Map() for (const rule of rules) { const safe = guarded(rule, report) for (const name of rule.commands) { if (!byName.has(name)) byName.set(name, safe) } } return name => byName.get(name) ?? byName.get(ANY_COMMAND) }