JSON

Decode JSON data.

Code

app "json-basic"
    packages {
        cli: "https://github.com/roc-lang/basic-cli/releases/download/0.7.0/bkGby8jb0tmZYsy2hg1E_B2QrCgcSTxdUlHtETwm5m4.tar.br",
        json: "https://github.com/lukewilliamboswell/roc-json/releases/download/v0.4.0/PJHoaxmf2rXTmGW42QZz0kPVFqQkrv8D31pRMchw2eA.tar.br",
    }
    imports [
        cli.Stdout,
        cli.Task,
        json.Core.{ jsonWithOptions },
        Decode.{ DecodeResult, fromBytesPartial },
    ]
    provides [main] to cli

main =
    requestBody = Str.toUtf8 "{\"Image\":{\"Animated\":false,\"Height\":600,\"Ids\":[116,943,234,38793],\"Thumbnail\":{\"Height\":125,\"Url\":\"http:\\/\\/www.example.com\\/image\\/481989943\",\"Width\":100},\"Title\":\"View from 15th Floor\",\"Width\":800}}"

    # This { fieldNameMapping: PascalCase } setting translates
    # incoming JSON fields from PascalCase (first letter capitalized)
    # to camelCase (first letter uncapitalized), which is what
    # Roc field names always use.
    decoder = jsonWithOptions { fieldNameMapping: PascalCase }

    decoded : DecodeResult ImageRequest
    decoded = fromBytesPartial requestBody decoder

    when decoded.result is
        Ok record ->
            Stdout.line "Successfully decoded image, title:\"\(record.image.title)\""

        Err _ ->
            {} <- Stdout.line "Error, failed to decode image" |> Task.await

            Task.err 1 # 1 is an exit code to indicate failure

ImageRequest : {
    image : {
        width : I64,
        height : I64,
        title : Str,
        thumbnail : {
            url : Str,
            height : F32,
            width : F32,
        },
        animated : Bool,
        ids : List U32,
    },
}

Output

Run this from the directory that has main.roc in it:

Note: --linker=legacy is used here because of https://github.com/roc-lang/roc/issues/3609

$ roc run --linker=legacy
Successfully decoded image, title:"View from 15th Floor"