-
-
Notifications
You must be signed in to change notification settings - Fork 320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decoding of records with missing fields. #6587
Conversation
d2cd4c1
to
6004f0c
Compare
6004f0c
to
2565580
Compare
Testing this PR with the below example and a minor update to roc-json to pass arguments to the finaliser. # switch to PR branch
cargo run -- run optional-decoding.roc
(Ok {count: 12, optional64: (@Option None)}) app "optional-decode"
packages {
cli: "../basic-cli/platform/main.roc",
json: "../roc-json/package/main.roc",
}
imports [cli.Stdout, json.Core.{ json }]
provides [main] to cli
main =
input = "{ \"count\": 12 }" |> Str.toUtf8
decoded : DecodeResult { optional64: Option U64, count: U32 }
decoded = Decode.fromBytesPartial input json
decoded.result
|> Inspect.toStr
|> Stdout.line
Option val := [None, Some val] implements [
Decoding { decoder: optionDecode },
Inspect, # auto derive
]
optionDecode : Decoder (Option val) fmt where val implements Decoding, fmt implements DecoderFormatting
optionDecode = Decode.custom \bytes, fmt ->
if bytes |> List.isEmpty then
{ result: Ok (@Option (None)), rest: [] }
else
when bytes |> Decode.decodeWith (Decode.decoder) fmt is
{ result: Ok res, rest } -> { result: Ok (@Option (Some res)), rest }
{ result: Err a, rest } -> { result: Err a, rest } |
3fc93ad
to
2565580
Compare
Tests are currently failing because the basic-cli has an "Env" decoder in it and needs to have the type annotation for it updated to reflect the fact that finalize has 2 params now |
4fde090
to
6588fd3
Compare
comments and clippy
6588fd3
to
56481dc
Compare
88b4d1c
to
e77759e
Compare
Are you ok with this change in general @rtfeldman, see also zulip? If so, I'll do the full review of this, do a new basic-cli release, etc. . |
I'm ok with it if @ayazhafiz is ok with it! 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach overall looks good. I would really prefer to have the implementation all in one file. It would make the diff easier to review and I don't think there is any benefit in splitting up the derivation across multiple files.
\#Derived.stateRecord -> | ||
when #Derived.stateRecord.first is | ||
\#Derived.stateRecord, #Derived.fmt -> | ||
when when #Derived.stateRecord.first is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not important for this PR but this formatting should be fixed.
I find enormous single files make it annoying to navigate through and find the parts I want, and I like how breaking things up makes it more clear when things are isolated from each other or dependent. But yeah it does make reviewing harder. I did do the splitting at the very end so I'm very happy to recombine if you like, or I can do the splitting in another PR. Just let me know :) |
What do you think of @faldor20's suggestions @ayazhafiz? |
6ebdb5e
to
612fa4c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @faldor20! I'll get started on a new basic-cli release.
EnvDecoding type matches changes to decoding from here: roc-lang/roc#6587
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @faldor20 and everyone else involved ❤️
I'm going to merge this Monday morning, because the tutorial in this PR is already updated for basic-cli 0.9.0, but that won't work unless you have Monday's nightly. |
See roc-lang/roc#6587 for context.
@Anton-4 Thanks a lot for all your work getting this deployed everywhere :) |
This is a test implementation of decoding records where some fields may not exist in the encoded data.
Before giving up decoding it will attempt to run the decoder for any missing field with a 0 byte input:
Decode.decodeWith [] Decode.decoder fmt
and if the decoder returns a success it will put that in the field.This allows us to define types that have specific behavior when decoding nothing. eg:
As we can see, if no bytes are given we just output a "None" value
A full code example: