import { StructOfArr } from "./types.ts"; import { zip } from "./utils.ts"; export class Rule { private separators: ({ kind: "word", word: string } | { kind: "end" })[]; private vars: V; public constructor(separators: string[], vars: V) { this.separators = separators.map(word => ({ kind: "word", word })); this.vars = vars; this.separators.push({ kind: "end" }); } public get(text: string): StructOfArr | null { const first_sep = this.separators[0] ?? ""; if (first_sep.kind === "end") { if (text.length > 0) return null; else return {} as StructOfArr; } let [val, rest] = split_once(text, first_sep.word); if (rest === null) return null; const result = {} as Record; for (const [key, sep] of zip(this.vars, this.separators.slice(1))) { if (sep.kind === "end") { result[key] = rest; break; } [val, rest] = split_once(rest, sep.word); if (rest === null) return null; result[key] = val; } return result as StructOfArr; } } function split_once(text: string, separator: string) { const cursor = text.indexOf(separator); if (cursor === -1) return [text, null] as const; const left = text.slice(0, cursor); const right = text.slice(cursor + separator.length); return [left, right] as const; }