add rule definition with minimal dsl
This commit is contained in:
parent
fa524a5976
commit
084c5a2574
5 changed files with 48 additions and 15 deletions
|
@ -1,10 +1,11 @@
|
||||||
#!/bin/env -S deno run
|
#!/bin/env -S deno run
|
||||||
|
|
||||||
import { extr } from "./mod.ts"
|
import { def } from "./mod.ts"
|
||||||
|
|
||||||
const date = ["month", " ", "day", " ", "h", ":", "m", ":", "s"] as const;
|
|
||||||
const service = extr("", ...date, " ", "device", " ", "service", "[", "pid", "]: ", "line");
|
const date = "{{month}} {{day}} {{h}}:{{m}}:{{s}}" as const;
|
||||||
const kernel_ = extr("", ...date, " ", "device", " kernel: ", "line");
|
const service = def(`${date} {{device}} {{service}}[{{pid}}]: {{line}}`);
|
||||||
|
const kernel_ = def(`${date} {{device}} kernel: {{line}}`);
|
||||||
|
|
||||||
const lines = [
|
const lines = [
|
||||||
"août 06 09:25:18 navis systemd[1]: Finished Load Kernel Module configfs.",
|
"août 06 09:25:18 navis systemd[1]: Finished Load Kernel Module configfs.",
|
||||||
|
|
34
lib/lib.ts
34
lib/lib.ts
|
@ -1,6 +1,7 @@
|
||||||
import { Rule } from "./rule.ts";
|
import { Rule } from "./rule.ts";
|
||||||
import { PairElts, StructOfArr } from "./types.ts";
|
import { PairElts, StructOfArr } from "./types.ts";
|
||||||
import { Extractor } from "./extractor.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>> {
|
export function extr<A extends string[]>(...args: A): Extractor<StructOfArr<PairElts<A>, string>> {
|
||||||
const seps = [] as 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))
|
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 { assertEquals } = await import("https://deno.land/std@0.224.0/assert/assert_equals.ts");
|
||||||
const vars = extr()
|
const vars = extr()
|
||||||
.or(extr("bonjour, ", 'animal', ", poilu"))
|
.or(extr("bonjour, ", 'animal', ", poilu"))
|
||||||
|
@ -26,3 +27,34 @@ Deno.test("types", async () => {
|
||||||
.get("bonjour, le chêne, feuillu");
|
.get("bonjour, le chêne, feuillu");
|
||||||
assertEquals({ vars }, { vars: { "arbre": "le chêne" } })
|
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" } })
|
||||||
|
})
|
||||||
|
|
10
lib/rule.ts
10
lib/rule.ts
|
@ -1,5 +1,5 @@
|
||||||
import { StructOfArr } from "./types.ts";
|
import { StructOfArr } from "./types.ts";
|
||||||
import { zip } from "./utils.ts";
|
import { split_once, zip } from "./utils.ts";
|
||||||
|
|
||||||
export class Rule<V extends string[]> {
|
export class Rule<V extends string[]> {
|
||||||
private separators: ({ kind: "word", word: string } | { kind: "end" })[];
|
private separators: ({ kind: "word", word: string } | { kind: "end" })[];
|
||||||
|
@ -32,11 +32,3 @@ export class Rule<V extends string[]> {
|
||||||
return result as StructOfArr<V, string>;
|
return result as StructOfArr<V, string>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,3 +12,11 @@ export function next<T>(iterator: Iterator<T>) {
|
||||||
if (result === undefined) return null;
|
if (result === undefined) return null;
|
||||||
else return result as T;
|
else return result as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export 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;
|
||||||
|
}
|
||||||
|
|
2
mod.ts
2
mod.ts
|
@ -1 +1 @@
|
||||||
export { extr } from "./lib/lib.ts"
|
export { extr, def } from "./lib/lib.ts"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue