add rule definition with minimal dsl
This commit is contained in:
parent
fa524a5976
commit
084c5a2574
5 changed files with 48 additions and 15 deletions
34
lib/lib.ts
34
lib/lib.ts
|
@ -1,6 +1,7 @@
|
|||
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<A extends string[]>(...args: A): Extractor<StructOfArr<PairElts<A>, string>> {
|
||||
const seps = [] as string[];
|
||||
|
@ -18,7 +19,7 @@ export function extr<A extends string[]>(...args: A): Extractor<StructOfArr<Pair
|
|||
return new Extractor(text => rule.get(text))
|
||||
}
|
||||
|
||||
Deno.test("types", async () => {
|
||||
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"))
|
||||
|
@ -26,3 +27,34 @@ Deno.test("types", async () => {
|
|||
.get("bonjour, le chêne, feuillu");
|
||||
assertEquals({ vars }, { vars: { "arbre": "le chêne" } })
|
||||
})
|
||||
|
||||
type ArrForDef<D extends string> =
|
||||
D extends "" ? [] :
|
||||
D extends `${infer W extends string}{{${infer V extends string}}}${infer R extends string}` ? [W, V, ...ArrForDef<R>] :
|
||||
D extends `${infer W extends string}` ? [W] :
|
||||
never;
|
||||
|
||||
export function def<D extends string>(def: D): Extractor<StructOfArr<PairElts<ArrForDef<D>>, 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<D>;
|
||||
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" } })
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue