Stub out Idv parser
This commit is contained in:
parent
a2df9a4142
commit
e90727a06c
4 changed files with 118 additions and 1 deletions
|
@ -6,6 +6,7 @@
|
||||||
<script src="js/debug.js"></script>
|
<script src="js/debug.js"></script>
|
||||||
<script>
|
<script>
|
||||||
document.body.append(...TickDebug());
|
document.body.append(...TickDebug());
|
||||||
|
document.body.append(...IdvDebug());
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
3
debug.ts
3
debug.ts
|
@ -1,3 +1,4 @@
|
||||||
import { TickDebug } from "./debug/tick";
|
import { TickDebug } from "./debug/tick";
|
||||||
|
import { IdvDebug } from "./debug/idv";
|
||||||
|
|
||||||
Object.assign(globalThis, { TickDebug });
|
Object.assign(globalThis, { TickDebug, IdvDebug });
|
||||||
|
|
43
debug/idv.ts
Normal file
43
debug/idv.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { h } from "../lib/html";
|
||||||
|
import { Idv, StringFromDocument } from "../lib/idv";
|
||||||
|
|
||||||
|
export function IdvDebug() {
|
||||||
|
const textarea = h(
|
||||||
|
"textarea",
|
||||||
|
{
|
||||||
|
cols: 80,
|
||||||
|
rows: 40,
|
||||||
|
oninput(ev) {
|
||||||
|
parse();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
`# Idv Testing Ground
|
||||||
|
Uid: 0
|
||||||
|
Shell: tclsh
|
||||||
|
Group: users
|
||||||
|
Group: sudo
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
const pre = h("pre");
|
||||||
|
|
||||||
|
function parse() {
|
||||||
|
try {
|
||||||
|
const idv = Idv.parse(textarea.value);
|
||||||
|
|
||||||
|
pre.textContent = JSON.stringify(
|
||||||
|
{
|
||||||
|
shell: idv.getProperty("Shell", String, StringFromDocument),
|
||||||
|
groups: idv.getList("Group", String, StringFromDocument),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
pre.textContent = String(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parse();
|
||||||
|
|
||||||
|
return [textarea, pre];
|
||||||
|
}
|
72
lib/idv.ts
Normal file
72
lib/idv.ts
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
export type DistinguisherParser<T> = (distinguisher: string) => T;
|
||||||
|
export type DocumentParser<T> = (document: string[]) => T;
|
||||||
|
|
||||||
|
const LEADING_WHITESPACE = /^([ \t]+)/;
|
||||||
|
const ENTRY = /^(.+?):\s*(.*)/;
|
||||||
|
|
||||||
|
export class Idv {
|
||||||
|
collections: Record<string, undefined | [string, string[]][]> = {};
|
||||||
|
|
||||||
|
public static parse(input: string): Idv {
|
||||||
|
const lines = input.split("\n").map((line) => line.trimEnd());
|
||||||
|
return Idv.parseLines(lines);
|
||||||
|
}
|
||||||
|
static parseLines(input: string[]): Idv {
|
||||||
|
const idv = new Idv();
|
||||||
|
let currentDocument: string[] = [];
|
||||||
|
|
||||||
|
input.forEach((line) => {
|
||||||
|
const indent = LEADING_WHITESPACE.exec(line)?.[1];
|
||||||
|
if (indent) {
|
||||||
|
// TODO
|
||||||
|
} else if (line == "") {
|
||||||
|
// TODO
|
||||||
|
} else if (line[0] == "#") {
|
||||||
|
// skip
|
||||||
|
} else {
|
||||||
|
const matches = ENTRY.exec(line);
|
||||||
|
if (matches) {
|
||||||
|
const [, collection, distinguisher] = matches;
|
||||||
|
|
||||||
|
if (idv.collections[collection] == undefined) {
|
||||||
|
idv.collections[collection] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDocument = [];
|
||||||
|
idv.collections[collection].push([distinguisher, currentDocument]);
|
||||||
|
} else {
|
||||||
|
throw new Error("Failed to parse a property");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return idv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getProperty<T>(
|
||||||
|
name: string,
|
||||||
|
parseDistinguisher: DistinguisherParser<T>,
|
||||||
|
parseDocument: DocumentParser<T>
|
||||||
|
): T | null {
|
||||||
|
const firstEntry = this.collections[name]?.[0];
|
||||||
|
return firstEntry && firstEntry[1].length > 0
|
||||||
|
? parseDocument(firstEntry[1])
|
||||||
|
: firstEntry?.[0]
|
||||||
|
? parseDistinguisher(firstEntry[0])
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getList<T>(
|
||||||
|
name: string,
|
||||||
|
parseDistinguisher: DistinguisherParser<T>,
|
||||||
|
parseDocument: DocumentParser<T>
|
||||||
|
): T[] {
|
||||||
|
return (this.collections[name] ?? []).map(([distinguisher, document]) =>
|
||||||
|
document.length > 0
|
||||||
|
? parseDocument(document)
|
||||||
|
: parseDistinguisher(distinguisher)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const StringFromDocument = (lines: string[]) => lines.join("\n");
|
Loading…
Add table
Reference in a new issue