66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import Tokenizer, { TokenizerOptions } from './tokenizer.ts';
|
|
import TokenParser, { StackElement, TokenParserOptions } from './tokenparser.ts';
|
|
import { JsonPrimitive, JsonKey, JsonStruct } from './utils/types.ts';
|
|
|
|
interface JSONParserOpts extends TokenizerOptions, TokenParserOptions {}
|
|
|
|
export default class JSONParser {
|
|
private tokenizer: Tokenizer;
|
|
private tokenParser: TokenParser;
|
|
|
|
constructor(opts: JSONParserOpts = {}) {
|
|
this.tokenizer = new Tokenizer(opts);
|
|
this.tokenParser = new TokenParser(opts);
|
|
|
|
this.tokenizer.onToken = this.tokenParser.write.bind(this.tokenParser);
|
|
this.tokenizer.onEnd = () => {
|
|
if (!this.tokenParser.isEnded) this.tokenParser.end();
|
|
};
|
|
|
|
this.tokenParser.onError = this.tokenizer.error.bind(this.tokenizer);
|
|
this.tokenParser.onEnd = () => {
|
|
if (!this.tokenizer.isEnded) this.tokenizer.end();
|
|
};
|
|
}
|
|
|
|
public get isEnded(): boolean {
|
|
return this.tokenizer.isEnded && this.tokenParser.isEnded;
|
|
}
|
|
|
|
public write(input: Iterable<number> | string): void {
|
|
this.tokenizer.write(input);
|
|
}
|
|
|
|
public end(): void {
|
|
this.tokenizer.end();
|
|
}
|
|
|
|
public set onToken(
|
|
cb: (token: number, value: JsonPrimitive, offset: number) => void
|
|
) {
|
|
this.tokenizer.onToken = cb;
|
|
}
|
|
|
|
public set onValue(
|
|
cb: (
|
|
value: JsonPrimitive | JsonStruct,
|
|
key: JsonKey | undefined,
|
|
parent: JsonStruct | undefined,
|
|
stack: StackElement[]
|
|
) => void
|
|
) {
|
|
this.tokenParser.onValue = cb;
|
|
}
|
|
|
|
public set onError(cb: (err: Error) => void) {
|
|
this.tokenizer.onError = cb;
|
|
}
|
|
|
|
public set onEnd(cb: () => void) {
|
|
this.tokenParser.onEnd = () => {
|
|
if (!this.tokenizer.isEnded) this.tokenizer.end();
|
|
cb.call(this.tokenParser);
|
|
};
|
|
}
|
|
}
|