import { Rule } from "./rule.ts"; import { PairElts, StructOfArr } from "./types.ts"; import { Extractor } from "./extractor.ts" import { split_once } from "./utils.ts"; export function extr(...args: A): Extractor, string>> { const seps = [] as string[]; const vars = [] as string[]; let pair = true; for (const arg of args) { if (pair) seps.push(arg); else vars.push(arg); pair = !pair; } const vars_ = vars as PairElts; const rule = new Rule(seps, vars_); return new Extractor(text => rule.get(text)) } Deno.test("extr_types", async () => { const { assertEquals } = await import("https://deno.land/std@0.224.0/assert/assert_equals.ts"); const vars = extr() .or(extr("bonjour, ", 'animal', ", poilu")) .or(extr("bonjour, ", 'arbre', ", feuillu")) .get("bonjour, le chêne, feuillu"); assertEquals({ vars }, { vars: { "arbre": "le chêne" } }) }) type ArrForDef = D extends "" ? [] : D extends `${infer W extends string}{{${infer V extends string}}}${infer R extends string}` ? [W, V, ...ArrForDef] : D extends `${infer W extends string}` ? [W] : never; export function def(def: D): Extractor>, string>> { const result = [] as string[]; let rest = def as string; while (true) { const [word, var_rest] = split_once(rest, "{{"); if (var_rest === null) break; const [var_, rest_] = split_once(var_rest, "}}"); if (rest_ === null) throw new Error(`Invalid rule near '${rest}'`); result.push(word, var_); rest = rest_; } if (rest.length > 0) result.push(rest); const args = result as ArrForDef; return extr(...args); } Deno.test("def_types", async () => { const { assertEquals } = await import("https://deno.land/std@0.224.0/assert/assert_equals.ts"); const vars = extr() .or(def("bonjour, {{animal}}, poilu")) .or(def("bonjour, {{arbre}}, feuillu")) .get("bonjour, le chêne, feuillu"); assertEquals({ vars }, { vars: { "arbre": "le chêne" } }) })