init
This commit is contained in:
commit
8c18398ae4
6 changed files with 111 additions and 0 deletions
34
lib/rule.ts
Normal file
34
lib/rule.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { StructOfArr } from "./types.ts";
|
||||
import { zip } from "./utils.ts";
|
||||
|
||||
export class Rule<V extends string[]> {
|
||||
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<V, string> | null {
|
||||
const first_sep = this.separators[0] ?? "";
|
||||
if (first_sep.kind === "end") {
|
||||
if (text.length > 0) return null;
|
||||
else return {} as StructOfArr<V, string>;
|
||||
}
|
||||
if (!text.includes(first_sep.word)) return null;
|
||||
let [val, rest] = text.split(first_sep.word, 2);
|
||||
const result = {} as Record<string, string>;
|
||||
for (const [key, sep] of zip(this.vars, this.separators.slice(1))) {
|
||||
if (sep.kind === "end") {
|
||||
result[key] = rest;
|
||||
break;
|
||||
}
|
||||
if (!rest.includes(sep.word)) return null;
|
||||
[val, rest] = rest.split(sep.word, 2);
|
||||
result[key] = val;
|
||||
}
|
||||
return result as StructOfArr<V, string>;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue