diff --git a/src/util/combo.js b/src/util/combo.js index dadc479..cb7f416 100644 --- a/src/util/combo.js +++ b/src/util/combo.js @@ -95,6 +95,19 @@ export const null_: Parser = new Parser((x) => { return success(x); }); +// The identity operation: a parser that always succeeds, emitting a +// `JsonObject` (not `any`) with the input. Used when you need a parser +// that matches anything: +// +// // Accepts an arbitrary heterogeneous array and returns its length +// C.fmap(C.array(C.raw), (a) => a.length) +// +// // Accepts a config file with dynamic plugin-specific data +// C.object({version: string, pluginConfig: C.dict(C.raw)}) +// +// To destructure the parsed value dynamically, pair with `fmap`. +export const raw: Parser = new Parser(success); + // Lift a plain value into a parser that always returns that value, // ignoring its input. export function pure(t: T): Parser { diff --git a/src/util/combo.test.js b/src/util/combo.test.js index 8309ef9..a790ada 100644 --- a/src/util/combo.test.js +++ b/src/util/combo.test.js @@ -75,6 +75,29 @@ describe("src/util/combo", () => { }); }); + describe("raw", () => { + it("parses strings", () => { + expect(C.raw.parseOrThrow("hey")).toEqual("hey"); + }); + it("parses numbers", () => { + expect(C.raw.parseOrThrow(123)).toEqual(123); + }); + it("parses booleans", () => { + expect(C.raw.parseOrThrow(true)).toEqual(true); + expect(C.raw.parseOrThrow(false)).toEqual(false); + }); + it("parses null", () => { + expect(C.raw.parseOrThrow(null)).toEqual(null); + }); + it("parses heterogeneous arrays", () => { + expect(C.raw.parseOrThrow([1, "two"])).toEqual([1, "two"]); + }); + it("parses heterogeneous objects", () => { + const input = {one: 2, three: "five"}; + expect(C.raw.parseOrThrow(input)).toEqual({one: 2, three: "five"}); + }); + }); + describe("pure", () => { it("does what it says on the tin", () => { type Color = "RED" | "GREEN" | "BLUE";