aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrkutly <mark.sauer.utley@gmail.com>2022-05-22 13:31:43 -0400
committerLouis Pilfold <louis@lpil.uk>2022-06-11 18:39:10 +0100
commit5a574dbbfa89cfb1d62b4acbc33c1a1033b24d01 (patch)
tree87d9a58c7cbc293a7f3ce9dcb824ecbe368ae4f1
parent0edd5bcc7ad03a8d61a44a88882bcbe3b2dddb2f (diff)
downloadgleam_json-5a574dbbfa89cfb1d62b4acbc33c1a1033b24d01.tar.gz
gleam_json-5a574dbbfa89cfb1d62b4acbc33c1a1033b24d01.zip
fix json converters
-rw-r--r--src/gleam/json.gleam8
-rw-r--r--src/gleam_json_ffi.mjs109
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)
}