adds docs for Json

This commit is contained in:
Luke Boswell 2023-03-15 16:30:39 +11:00
parent d8d3d252f1
commit 1fe56bcefb
No known key found for this signature in database
GPG Key ID: F6DB3C9DB47377B0

View File

@ -1,3 +1,36 @@
## JSON is a data format that is easy for humans to read and write. It is
## commonly used to exhange data between two systems such as a server and a
## client (e.g. web browser).
##
## This module implements functionality to serialise and de-serialise Roc types
## to and from JSON data. Using the `Encode` and `Decode` builtins this process
## can be achieved without the need to write custom encoder and decoder functions
## to parse UTF-8 strings.
##
## Here is a basic example which shows how to parse a JSON record into a Roc
## type named `Language` which includes a `name` field. The JSON string is
## decoded and then the field is encoded back into a UTF-8 string.
##
## ```
## Language : {
## name : Str,
## }
##
## jsonStr = Str.toUtf8 "{\"name\":\"Röc Lang\"}"
##
## result : Result Language _
## result =
## jsonStr
## |> Decode.fromBytes fromUtf8 # returns `Ok {name : "Röc Lang"}`
##
## name =
## decodedValue <- Result.map result
##
## Encode.toBytes decodedValue.name toUtf8
##
## expect name == Ok (Str.toUtf8 "\"Röc Lang\"")
## ```
##
interface Json
exposes [
Json,
@ -38,6 +71,8 @@ interface Json
Result,
]
## An opaque type with the `EncoderFormatting` and
## `DecoderFormatting` abilities.
Json := {} has [
EncoderFormatting {
u8: encodeU8,
@ -80,8 +115,10 @@ Json := {} has [
},
]
## Returns a JSON `Decoder`
toUtf8 = @Json {}
## Returns a JSON `Encoder`
fromUtf8 = @Json {}
numToBytes = \n ->
@ -498,6 +535,7 @@ expect
input = Str.toUtf8 " \n\r\tabc"
actual = eatWhitespace input
expected = Str.toUtf8 "abc"
actual == expected
# Test json string decoding with escapes
@ -505,6 +543,7 @@ expect
input = Str.toUtf8 "\"a\r\nbc\\\"xz\""
expected = Ok "a\r\nbc\\\"xz"
actual = Decode.fromBytes input fromUtf8
actual == expected
# Test json string encoding with escapes
@ -512,15 +551,14 @@ expect
input = "a\r\nbc\\\"xz"
expected = Str.toUtf8 "\"a\r\nbc\\\"xz\""
actual = Encode.toBytes input toUtf8
actual == expected
# Test json array decode empty list
expect
input = Str.toUtf8 "[ ]"
actual : Result (List U8) _
actual = Decode.fromBytes input fromUtf8
expected = Ok []
actual == expected
@ -528,38 +566,16 @@ expect
# Test json array decoding into integers
expect
input = Str.toUtf8 "[ 1,\n2,\t3]"
expected = [1, 2, 3]
actual : List U8
actual = Decode.fromBytes input fromUtf8 |> Result.withDefault []
actual : Result (List U8) _
actual = Decode.fromBytes input fromUtf8
expected = Ok [1, 2, 3]
actual == expected
# Test json array decoding into strings ignoring whitespace around values
expect
input = Str.toUtf8 "[\r\"one\" ,\t\"two\"\n,\n\"3\"\t]"
expected = ["one", "two", "3"]
actual : List Str
actual =
Decode.fromBytes input fromUtf8
|> Result.onErr handleJsonDecodeError
|> Result.withDefault []
actual = Decode.fromBytes input fromUtf8
expected = Ok ["one", "two", "3"]
actual == expected
# Helper for tests to handle Json decoding errors
handleJsonDecodeError = \err ->
when err is
Leftover bytes ->
when Str.fromUtf8 bytes is
Ok bs -> crash "ERROR: bytes left \(bs)"
Err _ ->
ls =
bytes
|> List.map Num.toStr
|> Str.joinWith ","
crash "ERROR: bytes left \(ls)"
TooShort -> crash "ERROR: input too short"