diff --git a/package-lock.json b/package-lock.json index 2562373..6e5fa20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,34 +9,174 @@ "version": "1.4.0", "license": "(LGPL-3.0 OR MPL-2.0)", "devDependencies": { - "rescript": "^11.0.1" + "rescript": "^12.0.0-beta.4" }, "engines": { "node": "*" } }, + "node_modules/@rescript/darwin-arm64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/darwin-arm64/-/darwin-arm64-12.0.0-beta.4.tgz", + "integrity": "sha512-UenADkeR86PyFJ89AY0utG5fi1/3DLEBHoof0DjgXpMhZoPg+fjXcxRGhtBpN1Bov59kBLxIDLX0T6ZkFtjbwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@rescript/darwin-x64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/darwin-x64/-/darwin-x64-12.0.0-beta.4.tgz", + "integrity": "sha512-aKSabtfetlVvA0EA2G4TBTlDH96CZsnmCMbsGwwMDvLLr4cmnmJoMO/nvgI5AdFcNUW/NGVtGVsgPfcmLd7EWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@rescript/linux-arm64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/linux-arm64/-/linux-arm64-12.0.0-beta.4.tgz", + "integrity": "sha512-UHClm/Gsdv5v2kLgEhkqfIsDeYSIuACGmHWPhskg93+EjeBHpPWr4DG/8XdhywZfTFgIGsIYzpZ3ejRfKq5X+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@rescript/linux-x64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/linux-x64/-/linux-x64-12.0.0-beta.4.tgz", + "integrity": "sha512-c7ueadv9lhK77sCi9zfQPkaz4vmzoW4U2b4GgUqkSzDlOxYT3ttWiC2+deGBJ26Q7CsWL/kFb0Hp2rydjkkexw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@rescript/win32-x64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/win32-x64/-/win32-x64-12.0.0-beta.4.tgz", + "integrity": "sha512-qMhBvqQp0wnKp+z1do79NHb/j3t50946P4QH01/ErtJpTLEJUyx6OzaEaNu5r4iu+AXAKtFG26497JICvuTWJg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.11.0" + } + }, "node_modules/rescript": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.0.1.tgz", - "integrity": "sha512-7T4PRp/d0+CBNnY6PYKffFqo9tGZlvnZpboF/n+8SKS+JZ6VvXJO7W538VPZXf3EYx1COGAWWvkF9e/HgSAqHg==", + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-12.0.0-beta.4.tgz", + "integrity": "sha512-Le3fnsa6MUDecmpnfIuJMA8cXraRLrdEd4Ho2m5OavTKbWgINzJiG3sqlnF1yPpWNPZ3nL5D8oRNakcpp1fbtg==", "dev": true, - "hasInstallScript": true, + "workspaces": [ + "packages/*", + "packages/@rescript/*", + "tests/dependencies/**", + "tests/analysis_tests/**", + "tests/docstring_tests", + "tests/gentype_tests/**", + "tests/tools_tests", + "scripts/res" + ], "bin": { - "bsc": "bsc", - "bstracing": "lib/bstracing", - "rescript": "rescript" + "bsc": "cli/bsc.js", + "bstracing": "cli/bstracing.js", + "rescript": "cli/rescript.js", + "rescript-legacy": "cli/rescript-legacy.js", + "rescript-tools": "cli/rescript-tools.js" }, "engines": { - "node": ">=10" + "node": ">=20.11.0" + }, + "optionalDependencies": { + "@rescript/darwin-arm64": "12.0.0-beta.4", + "@rescript/darwin-x64": "12.0.0-beta.4", + "@rescript/linux-arm64": "12.0.0-beta.4", + "@rescript/linux-x64": "12.0.0-beta.4", + "@rescript/win32-x64": "12.0.0-beta.4" } } }, "dependencies": { + "@rescript/darwin-arm64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/darwin-arm64/-/darwin-arm64-12.0.0-beta.4.tgz", + "integrity": "sha512-UenADkeR86PyFJ89AY0utG5fi1/3DLEBHoof0DjgXpMhZoPg+fjXcxRGhtBpN1Bov59kBLxIDLX0T6ZkFtjbwQ==", + "dev": true, + "optional": true + }, + "@rescript/darwin-x64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/darwin-x64/-/darwin-x64-12.0.0-beta.4.tgz", + "integrity": "sha512-aKSabtfetlVvA0EA2G4TBTlDH96CZsnmCMbsGwwMDvLLr4cmnmJoMO/nvgI5AdFcNUW/NGVtGVsgPfcmLd7EWQ==", + "dev": true, + "optional": true + }, + "@rescript/linux-arm64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/linux-arm64/-/linux-arm64-12.0.0-beta.4.tgz", + "integrity": "sha512-UHClm/Gsdv5v2kLgEhkqfIsDeYSIuACGmHWPhskg93+EjeBHpPWr4DG/8XdhywZfTFgIGsIYzpZ3ejRfKq5X+Q==", + "dev": true, + "optional": true + }, + "@rescript/linux-x64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/linux-x64/-/linux-x64-12.0.0-beta.4.tgz", + "integrity": "sha512-c7ueadv9lhK77sCi9zfQPkaz4vmzoW4U2b4GgUqkSzDlOxYT3ttWiC2+deGBJ26Q7CsWL/kFb0Hp2rydjkkexw==", + "dev": true, + "optional": true + }, + "@rescript/win32-x64": { + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/@rescript/win32-x64/-/win32-x64-12.0.0-beta.4.tgz", + "integrity": "sha512-qMhBvqQp0wnKp+z1do79NHb/j3t50946P4QH01/ErtJpTLEJUyx6OzaEaNu5r4iu+AXAKtFG26497JICvuTWJg==", + "dev": true, + "optional": true + }, "rescript": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.0.1.tgz", - "integrity": "sha512-7T4PRp/d0+CBNnY6PYKffFqo9tGZlvnZpboF/n+8SKS+JZ6VvXJO7W538VPZXf3EYx1COGAWWvkF9e/HgSAqHg==", - "dev": true + "version": "12.0.0-beta.4", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-12.0.0-beta.4.tgz", + "integrity": "sha512-Le3fnsa6MUDecmpnfIuJMA8cXraRLrdEd4Ho2m5OavTKbWgINzJiG3sqlnF1yPpWNPZ3nL5D8oRNakcpp1fbtg==", + "dev": true, + "requires": { + "@rescript/darwin-arm64": "12.0.0-beta.4", + "@rescript/darwin-x64": "12.0.0-beta.4", + "@rescript/linux-arm64": "12.0.0-beta.4", + "@rescript/linux-x64": "12.0.0-beta.4", + "@rescript/win32-x64": "12.0.0-beta.4" + } } } } diff --git a/package.json b/package.json index f26af36..b71fe2d 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,10 @@ "version": "1.4.0", "description": "Combinator library for JSON decoding and encoding. ", "scripts": { - "build": "rescript build -with-deps", - "start": "rescript build -w -with-deps", + "build": "rescript build", + "start": "rescript watch", "clean": "rescript clean", - "fmt": "rescript format -all", + "fmt": "rescript format -a", "test": "true" }, "engines": { @@ -28,9 +28,9 @@ "homepage": "https://github.com/glennsl/rescript-json-combinators#readme", "files": [ "src/*.res*", - "bsconfig.json" + "rescript.json" ], "devDependencies": { - "rescript": "^11.0.1" + "rescript": "^12.0.0-beta.4" } } diff --git a/bsconfig.json b/rescript.json similarity index 100% rename from bsconfig.json rename to rescript.json diff --git a/src/Json.res b/src/Json.res index 2a04671..5360a90 100644 --- a/src/Json.res +++ b/src/Json.res @@ -7,13 +7,18 @@ let decode = Decode.decode let parse = str => try Ok(str->Js.Json.parseExn) catch { - | Js.Exn.Error(ex) => Error(ex->Js.Exn.message->Js.Option.getWithDefault("Unknown error", _)) + | ex => + let message = + ex->JsExn.fromException->Option.flatMap(JsExn.message)->Option.getOr("Unknown error") + Error(message) } let parseExn = str => try str->Js.Json.parseExn catch { - | Js.Exn.Error(ex) => - raise(ParseError(ex->Js.Exn.message->Js.Option.getWithDefault("Unknown error", _))) + | ex => + let message = + ex->JsExn.fromException->Option.flatMap(JsExn.message)->Option.getOr("Unknown error") + throw(ParseError(message)) } @val external stringify: Js.Json.t => string = "JSON.stringify" diff --git a/src/Json_Decode.res b/src/Json_Decode.res index 3cf2afa..c226ae0 100644 --- a/src/Json_Decode.res +++ b/src/Json_Decode.res @@ -1,23 +1,23 @@ open Js.Json -type t<'a> = (. Js.Json.t) => 'a +type t<'a> = Js.Json.t => 'a type fieldDecoders = { - optional: 'a. (. string, t<'a>) => option<'a>, - required: 'a. (. string, t<'a>) => 'a, + optional: 'a. (string, t<'a>) => option<'a>, + required: 'a. (string, t<'a>) => 'a, } exception DecodeError(string) module Error = { - let expected = (kind, json) => raise(DecodeError(`Expected ${kind}, got ${stringify(json)}`)) + let expected = (kind, json) => throw(DecodeError(`Expected ${kind}, got ${stringify(json)}`)) } let custom = f => f -let id = (. json) => json +let id = json => json -let float = (. json) => { +let float = json => { if Js.typeof(json) != "number" { Error.expected("float", json) } @@ -25,7 +25,7 @@ let float = (. json) => { Obj.magic(json) } -let int = (. json) => { +let int = json => { if Js.typeof(json) != "number" { Error.expected("int", json) } @@ -39,7 +39,7 @@ let int = (. json) => { Obj.magic(json) } -let bool = (. json) => { +let bool = json => { if Js.typeof(json) != "boolean" { Error.expected("bool", json) } @@ -47,7 +47,7 @@ let bool = (. json) => { Obj.magic(json) } -let string = (. json) => { +let string = json => { if Js.typeof(json) != "string" { Error.expected("string", json) } @@ -55,196 +55,206 @@ let string = (. json) => { Obj.magic(json) } -let array = (decode) => (. json) => { - if !Js.Array.isArray(json) { - Error.expected("array", json) - } +let array = decode => + json => { + if !Js.Array.isArray(json) { + Error.expected("array", json) + } - let source: array = Obj.magic(json) - let target = %raw("new Array(json.length)") + let source: array = Obj.magic(json) + let target = %raw("new Array(json.length)") - for i in 0 to Array.length(source) - 1 { - try { - let value = decode(. %raw("json[i]")) - target->Array.unsafe_set(i, value) - } catch { - | DecodeError(msg) => raise(DecodeError(`${msg}\n\tin array at index ${string_of_int(i)}`)) + for i in 0 to Array.length(source) - 1 { + try { + let value = decode(%raw("json[i]")) + target->Array.setUnsafe(i, value) + } catch { + | DecodeError(msg) => throw(DecodeError(`${msg}\n\tin array at index ${Int.toString(i)}`)) + } } - } - target -} + target + } -let list = (decode) => (. json) => array(decode)(. json)->Array.to_list +let list = decode => json => array(decode)(json)->List.fromArray -let option = decode => (. json) => { - if Obj.magic(json) == Js.null { - None - } else { - Some(decode(. json)) +let option = decode => + json => { + if Obj.magic(json) == Js.null { + None + } else { + Some(decode(json)) + } } -} -let date = (. json) => string(. json)->Js.Date.fromString +let date = json => string(json)->Js.Date.fromString -let tuple2 = (decodeA, decodeB) => (. json) => { - if !Js.Array.isArray(json) { - Error.expected("array", json) - } +let tuple2 = (decodeA, decodeB) => + json => { + if !Js.Array.isArray(json) { + Error.expected("array", json) + } - let arr: array = Obj.magic(json) - if Array.length(arr) != 2 { - raise( - DecodeError( - `Expected array of length 2, got array of length ${Array.length(arr)->string_of_int}`, - ), - ) - } + let arr: array = Obj.magic(json) + if Array.length(arr) != 2 { + throw( + DecodeError( + `Expected array of length 2, got array of length ${Array.length(arr)->Int.toString}`, + ), + ) + } - try (decodeA(. arr->Array.unsafe_get(0)), decodeB(. arr->Array.unsafe_get(1))) catch { - | DecodeError(msg) => raise(DecodeError(`${msg}\n\tin pair`)) + try (decodeA(arr->Array.getUnsafe(0)), decodeB(arr->Array.getUnsafe(1))) catch { + | DecodeError(msg) => throw(DecodeError(`${msg}\n\tin pair`)) + } } -} let pair = tuple2 -let tuple3 = (decodeA, decodeB, decodeC) => (. json) => { - if !Js.Array.isArray(json) { - Error.expected("array", json) - } +let tuple3 = (decodeA, decodeB, decodeC) => + json => { + if !Js.Array.isArray(json) { + Error.expected("array", json) + } - let arr: array = Obj.magic(json) - if Array.length(arr) != 3 { - raise( - DecodeError( - `Expected array of length 3, got array of length ${Array.length(arr)->string_of_int}`, - ), - ) - } + let arr: array = Obj.magic(json) + if Array.length(arr) != 3 { + throw( + DecodeError( + `Expected array of length 3, got array of length ${Array.length(arr)->Int.toString}`, + ), + ) + } - try ( - decodeA(. arr->Array.unsafe_get(0)), - decodeB(. arr->Array.unsafe_get(1)), - decodeC(. arr->Array.unsafe_get(2)), - ) catch { - | DecodeError(msg) => raise(DecodeError(`${msg}\n\tin pair`)) + try ( + decodeA(arr->Array.getUnsafe(0)), + decodeB(arr->Array.getUnsafe(1)), + decodeC(arr->Array.getUnsafe(2)), + ) catch { + | DecodeError(msg) => throw(DecodeError(`${msg}\n\tin pair`)) + } } -} -let tuple4 = (decodeA, decodeB, decodeC, decodeD) => (. json) => { - if !Js.Array.isArray(json) { - Error.expected("array", json) - } +let tuple4 = (decodeA, decodeB, decodeC, decodeD) => + json => { + if !Js.Array.isArray(json) { + Error.expected("array", json) + } - let arr: array = Obj.magic(json) - if Array.length(arr) != 4 { - raise( - DecodeError( - `Expected array of length 4, got array of length ${Array.length(arr)->string_of_int}`, - ), - ) - } + let arr: array = Obj.magic(json) + if Array.length(arr) != 4 { + throw( + DecodeError( + `Expected array of length 4, got array of length ${Array.length(arr)->Int.toString}`, + ), + ) + } - try ( - decodeA(. arr->Array.unsafe_get(0)), - decodeB(. arr->Array.unsafe_get(1)), - decodeC(. arr->Array.unsafe_get(2)), - decodeD(. arr->Array.unsafe_get(3)), - ) catch { - | DecodeError(msg) => raise(DecodeError(`${msg}\n\tin pair`)) + try ( + decodeA(arr->Array.getUnsafe(0)), + decodeB(arr->Array.getUnsafe(1)), + decodeC(arr->Array.getUnsafe(2)), + decodeD(arr->Array.getUnsafe(3)), + ) catch { + | DecodeError(msg) => throw(DecodeError(`${msg}\n\tin pair`)) + } } -} -let dict = decode => (. json) => { - if Js.typeof(json) != "object" || Js.Array.isArray(json) || Obj.magic(json) == Js.null { - Error.expected("object", json) - } +let dict = decode => + json => { + if Js.typeof(json) != "object" || Js.Array.isArray(json) || Obj.magic(json) == Js.null { + Error.expected("object", json) + } - let source: Js.Dict.t = Obj.magic(json) - try Js.Dict.map(decode, source)->Obj.magic catch { - | DecodeError(msg) => raise(DecodeError(`${msg}\n\tin dict'`)) + let source: Js.Dict.t = Obj.magic(json) + try Js.Dict.map(decode, source)->Obj.magic catch { + | DecodeError(msg) => throw(DecodeError(`${msg}\n\tin dict'`)) + } } -} -let field = (key, decode) => (. json) => { - if Js.typeof(json) != "object" || Js.Array.isArray(json) || Obj.magic(json) == Js.null { - Error.expected("object", json) - } +let field = (key, decode) => + json => { + if Js.typeof(json) != "object" || Js.Array.isArray(json) || Obj.magic(json) == Js.null { + Error.expected("object", json) + } - if !(%raw("key in json")) { - raise(DecodeError(`${key} required`)) - } + if !(%raw("key in json")) { + throw(DecodeError(`${key} required`)) + } - try decode(. %raw("json[key]")) catch { - | DecodeError(msg) => raise(DecodeError(`${msg}\n\tat field '${key}'`)) + try decode(%raw("json[key]")) catch { + | DecodeError(msg) => throw(DecodeError(`${msg}\n\tat field '${key}'`)) + } } -} -let object = f => (. json) => { - if Js.typeof(json) != "object" || Js.Array.isArray(json) || Obj.magic(json) == Js.null { - raise(Error.expected("object", json)) - } +let object = f => + json => { + if Js.typeof(json) != "object" || Js.Array.isArray(json) || Obj.magic(json) == Js.null { + throw(Error.expected("object", json)) + } - let optional = (. key, decode) => { - if !(%raw("key in json")) { - None - } else { - try { - let value = decode(. %raw("json[key]")) - Some(value) - } catch { - | DecodeError(msg) => raise(DecodeError(`${msg}\n\tat field '${key}'`)) + let optional = (key, decode) => { + if !(%raw("key in json")) { + None + } else { + try { + let value = decode(%raw("json[key]")) + Some(value) + } catch { + | DecodeError(msg) => throw(DecodeError(`${msg}\n\tat field '${key}'`)) + } } } - } - let required = (. key, decode) => { - if !(%raw("key in json")) { - raise(DecodeError(`${key} required`)) - } + let required = (key, decode) => { + if !(%raw("key in json")) { + throw(DecodeError(`${key} required`)) + } - try decode(. %raw("json[key]")) catch { - | DecodeError(msg) => raise(DecodeError(`${msg}\n\tat field '${key}'`)) + try decode(%raw("json[key]")) catch { + | DecodeError(msg) => throw(DecodeError(`${msg}\n\tat field '${key}'`)) + } } - } - f({optional: optional, required: required}) -} + f({optional, required}) + } -let oneOf = decoders => (. json) => { - let errors = [] +let oneOf = decoders => + json => { + let errors = [] + + let rec loop = i => { + if i >= Array.length(decoders) { + throw( + DecodeError( + `All decoders given to oneOf failed. Here are all the errors:\n- ${errors->Js.Array2.joinWith( + "\n", + )}\nAnd the JSON being decoded: ${stringify(json)}`, + ), + ) + } - let rec loop = i => { - if i >= Array.length(decoders) { - raise( - DecodeError( - `All decoders given to oneOf failed. Here are all the errors:\n- ${errors->Js.Array2.joinWith( - "\n", - )}\nAnd the JSON being decoded: ${stringify(json)}`, - ), - ) + let decode = Array.getUnsafe(decoders, i) + try decode(json) catch { + | DecodeError(err) => + errors->Js.Array2.push(err)->ignore + loop(i + 1) + } } - let decode = Array.unsafe_get(decoders, i) - try decode(. json) catch { - | DecodeError(err) => - errors->Js.Array2.push(err)->ignore - loop(i + 1) - } + loop(0) } - loop(0) -} - -let map = (decode, f) => (. json) => f(. decode(. json)) +let map = (decode, f) => json => f(decode(json)) -let flatMap = (decodeA, f) => (. json) => { - let decodeB = f(. decodeA(. json)) - decodeB(. json) -} +let flatMap = (decodeA, f) => + json => { + let decodeB = f(decodeA(json)) + decodeB(json) + } -let indirect = f => (. json) => f()(. json) +let indirect = f => json => f()(json) let decode = (json, decode) => - try Ok(decode(. json)) catch { + try Ok(decode(json)) catch { | DecodeError(msg) => Error(msg) } diff --git a/src/Json_Decode.resi b/src/Json_Decode.resi index 55ef3bc..c2296bf 100644 --- a/src/Json_Decode.resi +++ b/src/Json_Decode.resi @@ -1,8 +1,8 @@ type t<'a> type fieldDecoders = { - optional: 'a. (. string, t<'a>) => option<'a>, - required: 'a. (. string, t<'a>) => 'a, + optional: 'a. (string, t<'a>) => option<'a>, + required: 'a. (string, t<'a>) => 'a, } exception DecodeError(string) @@ -11,7 +11,7 @@ module Error: { let expected: (string, Js.Json.t) => _ } -let custom: ((. Js.Json.t) => 'a) => t<'a> +let custom: (Js.Json.t => 'a) => t<'a> let id: t @@ -34,9 +34,9 @@ let dict: t<'a> => t> let field: (string, t<'a>) => t<'a> let oneOf: array> => t<'a> -let map: (t<'a>, (. 'a) => 'b) => t<'b> -let flatMap: (t<'a>, (. 'a) => t<'b>) => t<'b> +let map: (t<'a>, 'a => 'b) => t<'b> +let flatMap: (t<'a>, 'a => t<'b>) => t<'b> -let indirect: (() => t<'a>) => t<'a> +let indirect: (unit => t<'a>) => t<'a> let decode: (Js.Json.t, t<'a>) => result<'a, string> diff --git a/src/Json_Encode.res b/src/Json_Encode.res index 2229b93..eb8b999 100644 --- a/src/Json_Encode.res +++ b/src/Json_Encode.res @@ -16,43 +16,46 @@ external boolArray: array => Js.Json.t = "%identity" let array = encode => arr => arr->Js.Array2.map(x => encode(x))->jsonArray -let list = encode => l => - switch l { - | list{} => jsonArray([]) - | list{hd, ...tl} => - let arr = Array.make(l->List.length, hd->encode) - let rec fill = (i, l) => - switch l { - | list{} => arr - | list{hd, ...tl} => - Array.unsafe_set(arr, i, hd->encode) - fill(i + 1, tl) - } - fill(1, tl)->jsonArray - } +let list = encode => + l => + switch l { + | list{} => jsonArray([]) + | list{hd, ...tl} => + let arr = Array.make(~length=l->List.length, hd->encode) + let rec fill = (i, l) => + switch l { + | list{} => arr + | list{hd, ...tl} => + Array.setUnsafe(arr, i, hd->encode) + fill(i + 1, tl) + } + fill(1, tl)->jsonArray + } let object = props => props->Js.Dict.fromArray->jsonDict -let option = encode => opt => - switch opt { - | None => null - | Some(v) => v->encode - } +let option = encode => + opt => + switch opt { + | None => null + | Some(v) => v->encode + } -let withDefault = (default, encode) => opt => - switch opt { - | None => default - | Some(v) => v->encode - } +let withDefault = (default, encode) => + opt => + switch opt { + | None => default + | Some(v) => v->encode + } let date = date => date->Js.Date.toJSONUnsafe->string let pair = (encodeA, encodeB) => ((a, b)) => [a->encodeA, b->encodeB]->jsonArray let tuple2 = (encodeA, encodeB) => ((a, b)) => [a->encodeA, b->encodeB]->jsonArray -let tuple3 = (encodeA, encodeB, encodeC) => ((a, b, c)) => - [a->encodeA, b->encodeB, c->encodeC]->jsonArray -let tuple4 = (encodeA, encodeB, encodeC, encodeD) => ((a, b, c, d)) => - [a->encodeA, b->encodeB, c->encodeC, d->encodeD]->jsonArray +let tuple3 = (encodeA, encodeB, encodeC) => + ((a, b, c)) => [a->encodeA, b->encodeB, c->encodeC]->jsonArray +let tuple4 = (encodeA, encodeB, encodeC, encodeD) => + ((a, b, c, d)) => [a->encodeA, b->encodeB, c->encodeC, d->encodeD]->jsonArray let dict = encode => dict => Js.Dict.map(v => encode(v), dict)->jsonDict