From 4c1bff5b969eedb36691d06b0a0f113025e50100 Mon Sep 17 00:00:00 2001 From: Michael Bock Date: Fri, 25 Jun 2021 06:02:01 +0200 Subject: [PATCH 1/2] Add match function to Json module --- src/Json.ts | 45 +++++++++++++++++++++++++++++++++++++++++++++ test/Json.ts | 11 +++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/Json.ts b/src/Json.ts index fd2acbbb8..9ea53e798 100644 --- a/src/Json.ts +++ b/src/Json.ts @@ -60,3 +60,48 @@ export const parse = (s: string): Either => parseJSON(s, identity */ // tslint:disable-next-line: deprecation export const stringify = (a: A): Either => stringifyJSON(a, identity) + +// ----------------------------------------------------------------------------- +// destructors +// ----------------------------------------------------------------------------- + +/** + * Takes a function for each possible Json type and returns the result of the one from the position that matches the given data. + * + * @category destructors + * @example + * import * as J from 'fp-ts/Json' + * + * const typeOf = J.match( + * () => 'null', + * () => 'boolean', + * () => 'number', + * () => 'string', + * () => 'array', + * () => 'object' + * ) + * + * assert.deepStrictEqual(typeOf(32.2), 'number') + * assert.deepStrictEqual(typeOf(['a', 'b']), 'array') + * + * @since 2.10.6 + */ +export const match: ( + isNull: () => Z, + isBool: (x: boolean) => Z, + isNum: (x: number) => Z, + isStr: (x: string) => Z, + isArr: (x: Array) => Z, + isObj: (x: Record) => Z +) => (j: Json) => Z = (isNull, isBool, isNum, isStr, isArr, isObj) => (j) => + j === null + ? isNull() + : typeof j === 'boolean' + ? isBool(j) + : typeof j === 'number' + ? isNum(j) + : typeof j === 'string' + ? isStr(j) + : Array.isArray(j) + ? isArr(j) + : isObj(j as JsonRecord) diff --git a/test/Json.ts b/test/Json.ts index 060baf731..3013b8732 100644 --- a/test/Json.ts +++ b/test/Json.ts @@ -30,4 +30,15 @@ describe('Json', () => { U.deepStrictEqual(_.stringify(undefined as any), E.left(new Error('Converting unsupported structure to JSON'))) }) + + it('match', () => { + const t = () => true + const f = () => false + U.strictEqual(_.match(t, f, f, f, f, f)(null), true) + U.strictEqual(_.match(f, t, f, f, f, f)(true), true) + U.strictEqual(_.match(f, f, t, f, f, f)(32.2), true) + U.strictEqual(_.match(f, f, f, t, f, f)('dolphin'), true) + U.strictEqual(_.match(f, f, f, f, t, f)(['zebra', 'tiger']), true) + U.strictEqual(_.match(f, f, f, f, f, t)({ name: 'Toni', age: 35 }), true) + }) }) From b3c0a7869825bb1a9fa7fdab7dd9b319bb332c83 Mon Sep 17 00:00:00 2001 From: Michael Bock Date: Fri, 25 Jun 2021 12:23:34 +0200 Subject: [PATCH 2/2] Use `on` instead of `is` in Json/match --- src/Json.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Json.ts b/src/Json.ts index 9ea53e798..7e3f82a2c 100644 --- a/src/Json.ts +++ b/src/Json.ts @@ -87,21 +87,21 @@ export const stringify = (a: A): Either => stringifyJSON(a, * @since 2.10.6 */ export const match: ( - isNull: () => Z, - isBool: (x: boolean) => Z, - isNum: (x: number) => Z, - isStr: (x: string) => Z, - isArr: (x: Array) => Z, - isObj: (x: Record) => Z -) => (j: Json) => Z = (isNull, isBool, isNum, isStr, isArr, isObj) => (j) => + onNull: () => Z, + onBool: (x: boolean) => Z, + onNum: (x: number) => Z, + onStr: (x: string) => Z, + onArr: (x: JsonArray) => Z, + onObj: (x: JsonRecord) => Z +) => (j: Json) => Z = (onNull, onBool, onNum, onStr, onArr, onObj) => (j) => j === null - ? isNull() + ? onNull() : typeof j === 'boolean' - ? isBool(j) + ? onBool(j) : typeof j === 'number' - ? isNum(j) + ? onNum(j) : typeof j === 'string' - ? isStr(j) + ? onStr(j) : Array.isArray(j) - ? isArr(j) - : isObj(j as JsonRecord) + ? onArr(j) + : onObj(j as JsonRecord)