From b83ad81692ae07bf9825e50dbf29467a2f4d4d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20J=C3=A4ckel?= Date: Fri, 21 Jun 2024 13:25:32 +0200 Subject: [PATCH 1/3] Updated formating of examples. --- examples/optional.roc | 5 ++- examples/simple2.roc | 76 +++++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/examples/optional.roc b/examples/optional.roc index bc0e5f7..f36d0f1 100644 --- a/examples/optional.roc +++ b/examples/optional.roc @@ -8,7 +8,7 @@ import cli.Task import json.Json import json.OptionOrNull exposing [OptionOrNull] -Object : { firstName: Str, lastName: OptionOrNull Str } +Object : { firstName : Str, lastName : OptionOrNull Str } main = noneObj : Object @@ -33,5 +33,4 @@ main = # someJson == {"firstName":"Luke","lastName":"Boswell"} someJson = Encode.toBytes someObj Json.utf8 Stdout.line (someJson |> Str.fromUtf8 |> Result.withDefault "Failed to encode JSON") - - + diff --git a/examples/simple2.roc b/examples/simple2.roc index cec8f96..663533d 100644 --- a/examples/simple2.roc +++ b/examples/simple2.roc @@ -1,38 +1,38 @@ -app [main] { - cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.8.1/x8URkvfyi9I0QhmVG98roKBUs_AZRkLFwFJVJ3942YA.tar.br", - json: "../package/main.roc", # use release URL (ends in tar.br) for local example, see github.com/lukewilliamboswell/roc-json/releases -} - -import cli.Stdout -import cli.Task -import json.Json -import "data.json" as requestBody : List U8 - -main = - decoder = Json.utf8With {} - - decoded : Decode.DecodeResult (List DataRequest) - decoded = Decode.fromBytesPartial requestBody decoder - - when decoded.result is - Ok list -> - Stdout.line! "Successfully decoded list" - - when List.get list 0 is - Ok rec -> Stdout.line! "Name of first person is: $(rec.lastname)" - Err _ -> Stdout.line! "Error occurred in List.get" - - Err TooShort -> Stdout.line! "A TooShort error occurred" - -DataRequest : { - id : I64, - firstname : Str, - lastname : Str, - email : Str, - gender : Str, - ipaddress : Str, -} - -# => -# Successfully decoded list -# Name of first person is: Penddreth +app [main] { + cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.8.1/x8URkvfyi9I0QhmVG98roKBUs_AZRkLFwFJVJ3942YA.tar.br", + json: "../package/main.roc", # use release URL (ends in tar.br) for local example, see github.com/lukewilliamboswell/roc-json/releases +} + +import cli.Stdout +import cli.Task +import json.Json +import "data.json" as requestBody : List U8 + +main = + decoder = Json.utf8With {} + + decoded : Decode.DecodeResult (List DataRequest) + decoded = Decode.fromBytesPartial requestBody decoder + + when decoded.result is + Ok list -> + Stdout.line! "Successfully decoded list" + + when List.get list 0 is + Ok rec -> Stdout.line! "Name of first person is: $(rec.lastname)" + Err _ -> Stdout.line! "Error occurred in List.get" + + Err TooShort -> Stdout.line! "A TooShort error occurred" + +DataRequest : { + id : I64, + firstname : Str, + lastname : Str, + email : Str, + gender : Str, + ipaddress : Str, +} + +# => +# Successfully decoded list +# Name of first person is: Penddreth From db35bbfb110ad6e02cc9073aad9b57c90a538f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20J=C3=A4ckel?= Date: Fri, 21 Jun 2024 13:49:58 +0200 Subject: [PATCH 2/3] Fixed decoding JSON UTF8 codepoints. --- package/Json.roc | 83 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/package/Json.roc b/package/Json.roc index 1198641..b0fd02b 100644 --- a/package/Json.roc +++ b/package/Json.roc @@ -1143,10 +1143,83 @@ hexToUtf8 = \a, b, c, d -> k = jsonHexToDecimal c l = jsonHexToDecimal d - if i == 0 && j == 0 then - [decimalHexToByte k l] + cp = (16 * 16 * 16 * Num.toU32 i) + (16 * 16 * Num.toU32 j) + (16 * Num.toU32 k) + Num.toU32 l + codepointToUtf8 cp + +# Copied from https://github.com/roc-lang/unicode/blob/e1162d49e3a2c57ed711ecdee7dc8537a19479d8/ +# from package/CodePoint.roc and modified +codepointToUtf8 : U32 -> List U8 +codepointToUtf8 = \u32 -> + if u32 < 0x80 then + [Num.toU8 u32] + else if u32 < 0x800 then + byte1 = + u32 + |> Num.shiftRightBy 6 + |> Num.bitwiseOr 0b11000000 + |> Num.toU8 + + byte2 = + u32 + |> Num.bitwiseAnd 0b111111 + |> Num.bitwiseOr 0b10000000 + |> Num.toU8 + + [byte1, byte2] + else if u32 < 0x10000 then + byte1 = + u32 + |> Num.shiftRightBy 12 + |> Num.bitwiseOr 0b11100000 + |> Num.toU8 + + byte2 = + u32 + |> Num.shiftRightBy 6 + |> Num.bitwiseAnd 0b111111 + |> Num.bitwiseOr 0b10000000 + |> Num.toU8 + + byte3 = + u32 + |> Num.bitwiseAnd 0b111111 + |> Num.bitwiseOr 0b10000000 + |> Num.toU8 + + [byte1, byte2, byte3] + else if u32 < 0x110000 then + ## This was an invalid Unicode scalar value, even though it had the Roc type Scalar. + ## This should never happen! + # expect u32 < 0x110000 + crash "Impossible" else - [decimalHexToByte i j, decimalHexToByte k l] + byte1 = + u32 + |> Num.shiftRightBy 18 + |> Num.bitwiseOr 0b11110000 + |> Num.toU8 + + byte2 = + u32 + |> Num.shiftRightBy 12 + |> Num.bitwiseAnd 0b111111 + |> Num.bitwiseOr 0b10000000 + |> Num.toU8 + + byte3 = + u32 + |> Num.shiftRightBy 6 + |> Num.bitwiseAnd 0b111111 + |> Num.bitwiseOr 0b10000000 + |> Num.toU8 + + byte4 = + u32 + |> Num.bitwiseAnd 0b111111 + |> Num.bitwiseOr 0b10000000 + |> Num.toU8 + + [byte1, byte2, byte3, byte4] # Test for \u0074 == U+74 == 't' in Basic Multilingual Plane expect @@ -1163,10 +1236,10 @@ expect # Test for \u2c64 == U+2C64 == 'Ɽ' in Latin Extended-C expect actual = hexToUtf8 '2' 'C' '6' '4' - expected = [44, 100] + expected = [0xE2, 0xB1, 0xA4] actual == expected -unicodeReplacement = hexToUtf8 'f' 'f' 'd' 'd' +unicodeReplacement = [0xEF, 0xBF, 0xBD] replaceEscapedChars : { inBytes : List U8, outBytes : List U8 } -> { inBytes : List U8, outBytes : List U8 } replaceEscapedChars = \{ inBytes, outBytes } -> From eebb018950263cdbf9bc17cd02d2108cda80fa5c Mon Sep 17 00:00:00 2001 From: Luke Boswell Date: Mon, 2 Sep 2024 11:38:27 +1000 Subject: [PATCH 3/3] update flake --- .gitignore | 3 ++- flake.lock | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 5440b45..74c81af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ +examples/optional examples/simple1 examples/simple2 examples/tuple .DS_Store -generated-docs/ \ No newline at end of file +generated-docs/ diff --git a/flake.lock b/flake.lock index 92d4c36..c60a08a 100644 --- a/flake.lock +++ b/flake.lock @@ -102,11 +102,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1725110531, - "narHash": "sha256-Nrp1NNv2jpr39eA8ykup6qxKaiX1EoH7W3NmT9cVkUw=", + "lastModified": 1725148842, + "narHash": "sha256-MNYwbORN1m2LnLKRVYOPk2RbNzix9FhL3sZ1ldTWS/g=", "owner": "roc-lang", "repo": "roc", - "rev": "835ab1a203aac24c784f7198033f096a9e9b185f", + "rev": "a1c92737212e024c0eecbb176e1f8d9d4af1708b", "type": "github" }, "original": {