-
-
Notifications
You must be signed in to change notification settings - Fork 789
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
LSP: generate decoder for individual variants of multi variant type #4161
Comments
Yep, that was a thought I had as well. I think generating all decoders at once is good |
At that point would it not make sense to have one decoder for all of them together? Surely that would be the next step for everyone. |
How would it be implemented? Whatever that is, wouldn't we be nudging folks towards using the specific representation we pick? pub type Wibble {
Wobble(one: Int)
Woo(string: String)
}
pub fn wibble_decoder() {
// How would the LS combine the two basic decoders?
// Let's say we went for `one_of`.
decode.one_of(wobble_decoder(), [woo_decoder()])
}
pub fn wobble_decoder() { ... }
pub fn woo_decoder() { ... } If I had the building blocks I could choose how to compose those the way it makes sense for me, maybe in my case I'm using a tag to tell the two variants apart and I'd just end up deleting the "default" decoder generated by the LS to write this: pub fn wibble_decoder() {
use tag <- decode.field("tag", tag_decoder())
let inner_decoder = case tag {
WobbleTag -> wobble_decoder()
WooTag -> woo_decoder()
}
decode.at(["value"], inner_decoder)
}
fn tag_decoder() { ... } |
I think that last one would be close to what we would have as the default format. We couldn't use the first one as it may not always be valid due to structurally overlapping variant field sets. It wouldn't be always useful, but if it shares a format with a JSON encoder then we could enable people to more quickly create JSON servers and clients for their full stack Gleam. |
In that case it would also have to generate a custom type for the tag though, and how should it behave if any of those names are already taken? |
Why would we need to generate a custom tag for the tag? It would be a string in JSON and converting to and atom would be wasted work as we can compare strings. |
Then we'd have to come up with a "zero" value to pass to the failing case: pub fn wibble_decoder() {
use tag <- decode.field("tag", tag_decoder())
case tag {
"wobble" -> decode.at(["value"], wobble_decoder())
"woo" -> decode.at(["value"], woo_decoder())
_ -> decode.failure(todo as "what do we put here?")
}
} So the compiler would have to come up with a zero value for that type instead of a zero value for a variant |
That's also true for if we generate a custom type for the tag as deserialising that could fail. |
The generate decoder for type action is really nice. I think it would be great if we could make it work with multi variant types as well. We don't know how one could represent the type as a whole so generating a single decoder is out of the question but it would be incredibly useful if we could generate single decoders for each of the variants:
Would produce two separate decoders:
Then I would be free to choose how to combine those to decode a
Wibble
as a whole, saving on a lot of typing.Should the action trigger on the type saying "generate decoders for the variants" or should it trigger on a per-variant basis? I personally think it would be better to have it trigger on the type as a whole and generate all the decoders at once. I can't imagine a case in which I'd like to generate just a single decoder.
The text was updated successfully, but these errors were encountered: