Closed MM-MikeSauce closed 5 years ago
Here is the decoder I am currently using in my project:
decodeZone : Decoder Zone
decodeZone =
Decode.string
|> Decode.andThen
(\string ->
Dict.get string TimeZone.zones
|> Maybe.map (\zone -> zone ())
|> Maybe.map Decode.succeed
|> Maybe.withDefault (Decode.fail (string ++ " is not a valid time zone."))
)
Not sure how to write an encoder though.
Hi Michael,
Since you're decoding a Zone
from just its name, then I imagine you want to encode just its name as well.
You'll just want your decoder to return the name too:
decodeZone : Decoder ( String, Zone )
decodeZone =
Decode.string
|> Decode.andThen
(\string ->
case Dict.get string TimeZone.zones of
Just zone ->
Decode.succeed ( string, zone () )
Nothing ->
Decode.fail (string ++ " is not a valid time zone.")
)
And then store the name with the Zone
, so that later you can encode just the name using Json.Encode.string
.
Does this help?
Justin
Hmm, that would work just fine. However, I don't particularly like the idea of changing my model for the Zone
to a Tuple
. I like how clean my code is with only passing the Zone
around.
It's a nice idea if I cannot get an encoder written, so I may fall back on that solution. I appreciate the idea.
Just to maybe spawn some thoughts, I'm sharing what I have so far as a potential encoder:
encodeZone : Zone -> Encode.Value
encodeZone timeZone =
let
zoneString =
Dict.filter (\zoneName zone -> zone () == timeZone) TimeZone.zones
|> Dict.toList
|> List.head
|> Maybe.map (\( zoneName, zone ) -> zoneName)
|> Maybe.withDefault ""
in
Encode.string zoneString
I'm not going to lie, this isn't a valid solution in my opinion. Ideally, it should never reach the Maybe.withDefault
state here. And this is also assuming that filtering the Dict
would produce exactly one result.
I'm working on refining this idea further.
I agree; I would not use that version of encodeZone
.
You don't have to store the name and Zone
together in a tuple. You just have to store them both somewhere in your model. You can still pass just the Zone
around, and when it comes time to encode, you only need the name, not the Zone
. 😃
Fair point, I guess I'm worried they could get out of sync. Don't want to introduce the possibility for an impossible state!
Right on; I can appreciate that!
I'm going to close this for now, as while the purpose of this library is to enable things like the decoder above, I don't know if it should provide it. Thanks for the feature suggestion and for sharing how you're using the library. 👍
Right now, it's easy enough to get the
Zone
from a string using thezones
Dict
. However, what isn't as easy is encoding theZone
back into a string.It would be nice to have an encoder that did this. And since there would be an encoder, it would make sense to also have a decoder.