From 8361e09c120d5a0e862c20e35a73a479ed380c93 Mon Sep 17 00:00:00 2001 From: Louis Pilfold Date: Thu, 3 Aug 2023 13:31:34 +0100 Subject: [PATCH] Update for Gleam v0.30 --- CHANGELOG.md | 1 + gleam.toml | 2 + src/gleam/json.gleam | 167 ++++++++++-------------------- test/gleam_json_js_ffi_test.gleam | 123 ++++++++++++---------- test/gleam_json_test.gleam | 14 ++- 5 files changed, 130 insertions(+), 177 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6136f01..31e85df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - Updated error parsing for current V8 runtimes. +- Updated for Gleam v0.30.0. ## v0.5.1 - 2023-03-02 diff --git a/gleam.toml b/gleam.toml index 37c9042..520effa 100644 --- a/gleam.toml +++ b/gleam.toml @@ -1,5 +1,7 @@ name = "gleam_json" version = "0.5.1" +gleam = ">= 0.30.0" + licences = ["Apache-2.0"] description = "Work with JSON in Gleam" diff --git a/src/gleam/json.gleam b/src/gleam/json.gleam index 26c8bfc..927a75e 100644 --- a/src/gleam/json.gleam +++ b/src/gleam/json.gleam @@ -5,7 +5,7 @@ import gleam/option.{None, Option, Some} import gleam/dynamic.{Dynamic} import gleam/string_builder.{StringBuilder} -pub external type Json +pub type Json pub type DecodeError { UnexpectedEndOfInput @@ -41,30 +41,29 @@ pub fn decode( do_decode(from: json, using: decoder) } -if erlang { - fn do_decode( - from json: String, - using decoder: dynamic.Decoder(t), - ) -> Result(t, DecodeError) { - let bits = bit_string.from_string(json) - decode_bits(bits, decoder) - } +@target(erlang) +fn do_decode( + from json: String, + using decoder: dynamic.Decoder(t), +) -> Result(t, DecodeError) { + let bits = bit_string.from_string(json) + decode_bits(bits, decoder) } -if javascript { - fn do_decode( - from json: String, - using decoder: dynamic.Decoder(t), - ) -> Result(t, DecodeError) { - use dynamic_value <- result.then(decode_string(json)) - decoder(dynamic_value) - |> result.map_error(UnexpectedFormat) - } - - external fn decode_string(String) -> Result(Dynamic, DecodeError) = - "../gleam_json_ffi.mjs" "decode" +@target(javascript) +fn do_decode( + from json: String, + using decoder: dynamic.Decoder(t), +) -> Result(t, DecodeError) { + use dynamic_value <- result.then(decode_string(json)) + decoder(dynamic_value) + |> result.map_error(UnexpectedFormat) } +@target(javascript) +@external(javascript, "../gleam_json_ffi.mjs", "decode") +fn decode_string(a: String) -> Result(Dynamic, DecodeError) + /// Decode a JSON bit string into dynamically typed data which can be decoded /// into typed data with the `gleam/dynamic` module. /// @@ -94,17 +93,15 @@ pub fn decode_bits( |> result.map_error(UnexpectedFormat) } -if erlang { - external fn decode_to_dynamic(BitString) -> Result(Dynamic, DecodeError) = - "gleam_json_ffi" "decode" -} +@target(erlang) +@external(erlang, "gleam_json_ffi", "decode") +fn decode_to_dynamic(a: BitString) -> Result(Dynamic, DecodeError) -if javascript { - fn decode_to_dynamic(json: BitString) -> Result(Dynamic, DecodeError) { - case bit_string.to_string(json) { - Ok(string) -> decode_string(string) - Error(Nil) -> Error(UnexpectedByte("", 0)) - } +@target(javascript) +fn decode_to_dynamic(json: BitString) -> Result(Dynamic, DecodeError) { + case bit_string.to_string(json) { + Ok(string) -> decode_string(string) + Error(Nil) -> Error(UnexpectedByte("", 0)) } } @@ -124,15 +121,9 @@ pub fn to_string(json: Json) -> String { do_to_string(json) } -if erlang { - external fn do_to_string(Json) -> String = - "gleam_json_ffi" "json_to_string" -} - -if javascript { - external fn do_to_string(Json) -> String = - "../gleam_json_ffi.mjs" "json_to_string" -} +@external(erlang, "gleam_json_ffi", "json_to_string") +@external(javascript, "../gleam_json_ffi.mjs", "json_to_string") +fn do_to_string(a: Json) -> String /// Convert a JSON value into a string builder. /// @@ -151,15 +142,9 @@ pub fn to_string_builder(json: Json) -> StringBuilder { do_to_string_builder(json) } -if erlang { - external fn do_to_string_builder(Json) -> StringBuilder = - "gleam_json_ffi" "json_to_iodata" -} - -if javascript { - external fn do_to_string_builder(Json) -> StringBuilder = - "../gleam_json_ffi.mjs" "json_to_string" -} +@external(erlang, "gleam_json_ffi", "json_to_iodata") +@external(javascript, "../gleam_json_ffi.mjs", "json_to_string") +fn do_to_string_builder(a: Json) -> StringBuilder /// Encode a string into JSON, using normal JSON escaping. /// @@ -174,15 +159,9 @@ pub fn string(input: String) -> Json { do_string(input) } -if erlang { - external fn do_string(String) -> Json = - "gleam_json_ffi" "string" -} - -if javascript { - external fn do_string(String) -> Json = - "../gleam_json_ffi.mjs" "identity" -} +@external(erlang, "gleam_json_ffi", "string") +@external(javascript, "../gleam_json_ffi.mjs", "identity") +fn do_string(a: String) -> Json /// Encode a bool into JSON. /// @@ -197,15 +176,9 @@ pub fn bool(input: Bool) -> Json { do_bool(input) } -if erlang { - external fn do_bool(Bool) -> Json = - "gleam_json_ffi" "bool" -} - -if javascript { - external fn do_bool(Bool) -> Json = - "../gleam_json_ffi.mjs" "identity" -} +@external(erlang, "gleam_json_ffi", "bool") +@external(javascript, "../gleam_json_ffi.mjs", "identity") +fn do_bool(a: Bool) -> Json /// Encode an int into JSON. /// @@ -220,15 +193,9 @@ pub fn int(input: Int) -> Json { do_int(input) } -if erlang { - external fn do_int(Int) -> Json = - "gleam_json_ffi" "int" -} - -if javascript { - external fn do_int(Int) -> Json = - "../gleam_json_ffi.mjs" "identity" -} +@external(erlang, "gleam_json_ffi", "int") +@external(javascript, "../gleam_json_ffi.mjs", "identity") +fn do_int(a: Int) -> Json /// Encode an float into JSON. /// @@ -243,15 +210,9 @@ pub fn float(input: Float) -> Json { do_float(input) } -if erlang { - external fn do_float(input: Float) -> Json = - "gleam_json_ffi" "float" -} - -if javascript { - external fn do_float(input: Float) -> Json = - "../gleam_json_ffi.mjs" "identity" -} +@external(erlang, "gleam_json_ffi", "float") +@external(javascript, "../gleam_json_ffi.mjs", "identity") +fn do_float(input input: Float) -> Json /// The JSON value null. /// @@ -266,15 +227,9 @@ pub fn null() -> Json { do_null() } -if erlang { - external fn do_null() -> Json = - "gleam_json_ffi" "null" -} - -if javascript { - external fn do_null() -> Json = - "../gleam_json_ffi.mjs" "do_null" -} +@external(erlang, "gleam_json_ffi", "null") +@external(javascript, "../gleam_json_ffi.mjs", "do_null") +fn do_null() -> Json /// Encode an optional value into JSON, using null if it the `None` variant. /// @@ -313,15 +268,9 @@ pub fn object(entries: List(#(String, Json))) -> Json { do_object(entries) } -if erlang { - external fn do_object(entries: List(#(String, Json))) -> Json = - "gleam_json_ffi" "object" -} - -if javascript { - external fn do_object(entries: List(#(String, Json))) -> Json = - "../gleam_json_ffi.mjs" "object" -} +@external(erlang, "gleam_json_ffi", "object") +@external(javascript, "../gleam_json_ffi.mjs", "object") +fn do_object(entries entries: List(#(String, Json))) -> Json /// Encode a list into a JSON array. /// @@ -351,12 +300,6 @@ pub fn preprocessed_array(from: List(Json)) -> Json { do_preprocessed_array(from) } -if erlang { - external fn do_preprocessed_array(from: List(Json)) -> Json = - "gleam_json_ffi" "array" -} - -if javascript { - external fn do_preprocessed_array(from: List(Json)) -> Json = - "../gleam_json_ffi.mjs" "array" -} +@external(erlang, "gleam_json_ffi", "array") +@external(javascript, "../gleam_json_ffi.mjs", "array") +fn do_preprocessed_array(from from: List(Json)) -> Json diff --git a/test/gleam_json_js_ffi_test.gleam b/test/gleam_json_js_ffi_test.gleam index f746ce2..df1b763 100644 --- a/test/gleam_json_js_ffi_test.gleam +++ b/test/gleam_json_js_ffi_test.gleam @@ -1,67 +1,76 @@ -if javascript { - import gleam/json.{DecodeError, UnexpectedByte, UnexpectedEndOfInput} - import gleeunit/should +@target(javascript) +import gleam/json.{DecodeError, UnexpectedByte, UnexpectedEndOfInput} +@target(javascript) +import gleeunit/should - type StandardError { - StandardError(message: String) - } - - // === End of input tests === // - pub fn chromium_end_of_input_test() { - "Unexpected end of JSON input" - |> StandardError - |> get_json_decode_error("") - |> should.equal(UnexpectedEndOfInput) - } +@target(javascript) +type StandardError { + StandardError(message: String) +} - pub fn spidermonkey_end_of_input_test() { - "JSON.parse: unexpected end of data at line 1 column 1 of the JSON data" - |> StandardError - |> get_json_decode_error("") - |> should.equal(UnexpectedEndOfInput) - } +// === End of input tests === // +@target(javascript) +pub fn chromium_end_of_input_test() { + "Unexpected end of JSON input" + |> StandardError + |> get_json_decode_error("") + |> should.equal(UnexpectedEndOfInput) +} - pub fn javascript_core_end_of_input_test() { - "JSON Parse error: Unexpected EOF" - |> StandardError - |> get_json_decode_error("") - |> should.equal(UnexpectedEndOfInput) - } +@target(javascript) +pub fn spidermonkey_end_of_input_test() { + "JSON.parse: unexpected end of data at line 1 column 1 of the JSON data" + |> StandardError + |> get_json_decode_error("") + |> should.equal(UnexpectedEndOfInput) +} - // === Unexpected byte tests === // - pub fn chromium_unexpected_byte_test() { - "Unexpected token a in JSON at position 5" - |> StandardError - |> get_json_decode_error("{\"b\":a}") - |> should.equal(UnexpectedByte(byte: "0x61", position: 5)) - } +@target(javascript) +pub fn javascript_core_end_of_input_test() { + "JSON Parse error: Unexpected EOF" + |> StandardError + |> get_json_decode_error("") + |> should.equal(UnexpectedEndOfInput) +} - pub fn spidermonkey_unexpected_byte_test() { - "JSON.parse: expected property name or '}' at line 1 column 6 of the JSON data" - |> StandardError - |> get_json_decode_error("{\"b\":a}") - |> should.equal(UnexpectedByte(byte: "0x61", position: 5)) - } +// === Unexpected byte tests === // +@target(javascript) +pub fn chromium_unexpected_byte_test() { + "Unexpected token a in JSON at position 5" + |> StandardError + |> get_json_decode_error("{\"b\":a}") + |> should.equal(UnexpectedByte(byte: "0x61", position: 5)) +} - pub fn javascript_core_unexpected_byte_test() { - "JSON Parse error: Unexpected identifier \"a\"" - |> StandardError - |> get_json_decode_error("{\"b\":a}") - |> should.equal(UnexpectedByte(byte: "0x61", position: 0)) - } +@target(javascript) +pub fn spidermonkey_unexpected_byte_test() { + "JSON.parse: expected property name or '}' at line 1 column 6 of the JSON data" + |> StandardError + |> get_json_decode_error("{\"b\":a}") + |> should.equal(UnexpectedByte(byte: "0x61", position: 5)) +} - pub fn spidermonkey_multiline_unexpected_byte_test() { - "JSON.parse: expected property name or '}' at line 2 column 6 of the JSON data" - |> StandardError - |> get_json_decode_error("{\n\"b\": a\n}") - |> should.equal(UnexpectedByte(byte: "0x61", position: 7)) +@target(javascript) +pub fn javascript_core_unexpected_byte_test() { + "JSON Parse error: Unexpected identifier \"a\"" + |> StandardError + |> get_json_decode_error("{\"b\":a}") + |> should.equal(UnexpectedByte(byte: "0x61", position: 0)) +} - "JSON.parse: expected double-quoted property name at line 3 column 1 of the JSON data" - |> StandardError - |> get_json_decode_error("{\n\"b\": \"x\",\na\n}") - |> should.equal(UnexpectedByte(byte: "0x61", position: 12)) - } +@target(javascript) +pub fn spidermonkey_multiline_unexpected_byte_test() { + "JSON.parse: expected property name or '}' at line 2 column 6 of the JSON data" + |> StandardError + |> get_json_decode_error("{\n\"b\": a\n}") + |> should.equal(UnexpectedByte(byte: "0x61", position: 7)) - external fn get_json_decode_error(StandardError, String) -> DecodeError = - "./gleam_json_ffi.mjs" "getJsonDecodeError" + "JSON.parse: expected double-quoted property name at line 3 column 1 of the JSON data" + |> StandardError + |> get_json_decode_error("{\n\"b\": \"x\",\na\n}") + |> should.equal(UnexpectedByte(byte: "0x61", position: 12)) } + +@target(javascript) +@external(javascript, "./gleam_json_ffi.mjs", "getJsonDecodeError") +fn get_json_decode_error(a: StandardError, b: String) -> DecodeError diff --git a/test/gleam_json_test.gleam b/test/gleam_json_test.gleam index 69c5550..f27edce 100644 --- a/test/gleam_json_test.gleam +++ b/test/gleam_json_test.gleam @@ -130,14 +130,12 @@ fn should_encode(data: Json, expected: String) { |> should.equal(json.to_string(data)) } -if erlang { - fn empty_list_decode_error() -> dynamic.DecodeError { - dynamic.DecodeError(expected: "Int", found: "List", path: []) - } +@target(erlang) +fn empty_list_decode_error() -> dynamic.DecodeError { + dynamic.DecodeError(expected: "Int", found: "List", path: []) } -if javascript { - fn empty_list_decode_error() { - dynamic.DecodeError(expected: "Int", found: "Tuple of 0 elements", path: []) - } +@target(javascript) +fn empty_list_decode_error() { + dynamic.DecodeError(expected: "Int", found: "Tuple of 0 elements", path: []) }