diff options
author | mrkutly <mark.sauer.utley@gmail.com> | 2022-05-22 13:31:43 -0400 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2022-06-11 18:39:10 +0100 |
commit | 5a574dbbfa89cfb1d62b4acbc33c1a1033b24d01 (patch) | |
tree | 87d9a58c7cbc293a7f3ce9dcb824ecbe368ae4f1 | |
parent | 0edd5bcc7ad03a8d61a44a88882bcbe3b2dddb2f (diff) | |
download | gleam_json-5a574dbbfa89cfb1d62b4acbc33c1a1033b24d01.tar.gz gleam_json-5a574dbbfa89cfb1d62b4acbc33c1a1033b24d01.zip |
fix json converters
-rw-r--r-- | src/gleam/json.gleam | 8 | ||||
-rw-r--r-- | src/gleam_json_ffi.mjs | 109 |
2 files changed, 41 insertions, 76 deletions
diff --git a/src/gleam/json.gleam b/src/gleam/json.gleam index 5faaa48..5670949 100644 --- a/src/gleam/json.gleam +++ b/src/gleam/json.gleam @@ -158,7 +158,7 @@ if erlang { if javascript { external fn do_string(String) -> Json = - "../gleam_json_ffi.mjs" "identity" + "../gleam_json_ffi.mjs" "string" } /// Encode a bool into JSON. @@ -181,7 +181,7 @@ if erlang { if javascript { external fn do_bool(Bool) -> Json = - "../gleam_json_ffi.mjs" "identity" + "../gleam_json_ffi.mjs" "bool" } /// Encode an int into JSON. @@ -204,7 +204,7 @@ if erlang { if javascript { external fn do_int(Int) -> Json = - "../gleam_json_ffi.mjs" "identity" + "../gleam_json_ffi.mjs" "int" } /// Encode an float into JSON. @@ -227,7 +227,7 @@ if erlang { if javascript { external fn do_float(input: Float) -> Json = - "../gleam_json_ffi.mjs" "identity" + "../gleam_json_ffi.mjs" "float" } /// The JSON value null. diff --git a/src/gleam_json_ffi.mjs b/src/gleam_json_ffi.mjs index e7cdecd..b8e69d5 100644 --- a/src/gleam_json_ffi.mjs +++ b/src/gleam_json_ffi.mjs @@ -1,65 +1,6 @@ -import { Ok, Error, CustomType } from './gleam.mjs' +import { Ok, Error, toList } from './gleam.mjs' import { bit_string_to_string } from '../../gleam_stdlib/dist/gleam_stdlib.mjs' - -export class DecodeError extends CustomType { - get __gleam_prelude_variant__() { - return "DecodeError"; - } -} - -export class UnexpectedEndOfInput extends CustomType { - static isInstance(err) { - return err.message === 'Unexpected end of JSON input' - } - - get __gleam_prelude_variant__() { - return "UnexpectedEndOfInput" - } -} - -export class UnexpectedByte extends CustomType { - static regex = /Unexpected token (.) in JSON at position (\d+)/ - - static isInstance(err) { - return this.regex.test(err) - } - - constructor(err) { - super() - const match = UnexpectedByte.regex.exec(err.message) - this.byte = "0x" + match[1].charCodeAt(0).toString(16).toUpperCase() - this.position = Number(match[2]) - } - - get __gleam_prelude_variant__() { - return `UnexpectedByte`; - } -} - -export class UnexpectedSequence extends CustomType { - static isInstance(err) { - return false - } - - get __gleam_prelude_variant__() { - return "UnexpectedSequence"; - } -} - -export class UnexpectedFormat extends CustomType { - static isInstance(err) { - return false - } - - constructor(decodeErrs) { - super() - this[0] = decodeErrs - } - - get __gleam_prelude_variant__() { - return "UnexpectedFormat"; - } -} +import { UnexpectedByte, UnexpectedEndOfInput, UnexpectedFormat } from './gleam/json.mjs' export function json_to_string(json) { return JSON.stringify(json) @@ -77,10 +18,23 @@ export function do_null() { return null } -export function identity(x) { - return x +export function string(x) { + return json_to_string(x) +} + +export function int(x) { + return parseInt(json_to_string(x), 10) +} + +export function float(x) { + return parseFloat(json_to_string(x), 10) +} + +export function bool(x) { + return Boolean(x) } + export function decode(bit_string) { const stringResult = bit_string_to_string(bit_string) if (!stringResult.isOk()) return stringResult @@ -88,18 +42,29 @@ export function decode(bit_string) { const result = JSON.parse(stringResult[0]) return new Ok(result) } catch (err) { - return getJsonDecodeError(err) + return new Error(getJsonDecodeError(err)) } } function getJsonDecodeError(stdErr) { - const ErrClass = [ - UnexpectedByte, - UnexpectedEndOfInput, - UnexpectedFormat, - UnexpectedSequence, - ].find((klass) => klass.isInstance(stdErr)) + if (isUnexpectedByte(stdErr)) return new toUnexpectedByteError(stdErr) + if (isUnexpectedEndOfInput(stdErr)) return new UnexpectedEndOfInput() + return undefined +} + +function isUnexpectedEndOfInput(err) { + return err.message === 'Unexpected end of JSON input' +} + +const unexpectedByteRegex = /Unexpected token (.) in JSON at position (\d+)/ + +function isUnexpectedByte(err) { + return unexpectedByteRegex.test(err) +} - if (ErrClass) return new Error(new ErrClass(stdErr)) - else return new Error() +function toUnexpectedByteError(err) { + const match = unexpectedByteRegex.exec(err.message) + const byte = "0x" + match[1].charCodeAt(0).toString(16).toUpperCase() + const position = Number(match[2]) + return new UnexpectedByte(byte, position) } |