import { exception2Result, Result } from "./result.js"; import { AsyncToDecoder, ToDecoder, TxtEnDecoder, TxtEnDecoderSingleton as TxtEnDecoderSingleton } from "./txt-en-decoder.js"; export interface JSONEnDecoder { // eslint-disable-next-line @typescript-eslint/no-explicit-any stringify(input: Result | T, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; asyncStringify( input: Promise | T>, // eslint-disable-next-line @typescript-eslint/no-explicit-any replacer?: (this: any, key: string, value: any) => any, space?: string | number, ): Promise; uint8ify( input: Result | T, // eslint-disable-next-line @typescript-eslint/no-explicit-any replacer?: (this: any, key: string, value: any) => any, space?: string | number, ): Uint8Array; asyncUint8ify( input: Promise | T>, // eslint-disable-next-line @typescript-eslint/no-explicit-any replacer?: (this: any, key: string, value: any) => any, space?: string | number, ): Promise>; // eslint-disable-next-line @typescript-eslint/no-explicit-any parse(input: ToDecoder, reviver?: (this: any, key: string, value: any) => any): Result; // eslint-disable-next-line @typescript-eslint/no-explicit-any asyncParse(input: AsyncToDecoder, reviver?: (this: any, key: string, value: any) => any): Promise>; } class JSONOps implements JSONEnDecoder { readonly txtOps: TxtEnDecoder; constructor(txtOps: TxtEnDecoder) { this.txtOps = txtOps; } async asyncStringify( input: Promise | T>, // eslint-disable-next-line @typescript-eslint/no-explicit-any replacer?: (this: any, key: string, value: any) => any, space?: string | number, ): Promise { const resolved = await input; return this.stringify(resolved, replacer, space); } async asyncUint8ify( input: Promise | T>, // eslint-disable-next-line @typescript-eslint/no-explicit-any replacer?: (this: any, key: string, value: any) => any, space?: string | number, ): Promise> { const resolved = await input; return this.uint8ify(resolved, replacer, space); } // eslint-disable-next-line @typescript-eslint/no-explicit-any async asyncParse(input: AsyncToDecoder, reviver?: (this: any, key: string, value: any) => any): Promise> { return this.parse(await this.txtOps.asyncDecode(input), reviver); } // eslint-disable-next-line @typescript-eslint/no-explicit-any stringify(input: Result | T, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string { return JSON.stringify(Result.Is(input) ? input.unwrap() : input, replacer, space); } uint8ify( input: Result | T, // eslint-disable-next-line @typescript-eslint/no-explicit-any replacer?: (this: any, key: string, value: any) => any, space?: string | number, ): Uint8Array { return this.txtOps.encode(this.stringify(input, replacer, space)); } // eslint-disable-next-line @typescript-eslint/no-explicit-any parse(input: ToDecoder, reviver?: (this: any, key: string, value: any) => any): Result { return exception2Result(() => JSON.parse(this.txtOps.decode(input), reviver) as T) as Result; } } let jsonEnDecoder: JSONEnDecoder; export function JSONEnDecoderSingleton(txtEnde?: TxtEnDecoder): JSONEnDecoder { let needNew = false; if (txtEnde && txtEnde !== TxtEnDecoderSingleton()) { needNew = !!txtEnde; txtEnde = txtEnde ?? TxtEnDecoderSingleton(); } if (needNew && txtEnde) { return new JSONOps(txtEnde); } jsonEnDecoder = jsonEnDecoder ?? new JSONOps(TxtEnDecoderSingleton()); return jsonEnDecoder; }