Add `fromJsonValue` or `fromObject` helper
Closed this issue · 3 comments
I got a little stuck when trying to decode a JsonValue
(which is an object) because turning it into a string gave me "[object Object]"
, which obviously won't decode correctly. I resolved this with Decode.fromValue "" ...
, but this doesn't feel quite as intuitive to me.
I think adding a Decode.fromObject
or Decode.fromJsonValue
will make the intended use path pretty clear and help reduce confusion from other newbies like myself.
This seems rather straightforward, so I'm more than willing to take a stab at it. I'm curious if this was intentionally avoided for some reason, though.
This is kind of intended because we don't know at what place of the path it is being called. I know that in the past some people called Decode.fromValue
deep in their JSON structure.
When calling it at the root, you should call Decode.fromValue "$" ...
$
meaning the root of the JSON and will be used for reporting the correct path in case of error.
Also, Decode.fromValue
is exposed but it was more intended to be an internal feature of Thoth.Json.
Personally, I think what is missing is probably a doc comment explaining how to use it, so people can have the explanation available from their IDE tooltips.
This is kind of intended because we don't know at what place of the path it is being called. I know that in the past some people called
Decode.fromValue
deep in their JSON structure.
Hmm, I think I'm missing something. If I have a type with a property that's a JsonValue
, wouldn't I be able to decode that value from the root? Or is the whole wrapping object given with the path to that value? Would creating a function Decode.fromRoot
help here / do what I want?
I'm fine adding some comments if you don't think this kind of function would be helpful.
I think what you are looking for would be like this:
module Decode =
let fromRootValue (dec : Decoder<_>) =
Decode.fromValue "$" dec
If you have a type containing a JsonValue
property it might look like this:
type Foo =
{
X : int
J : JsonValue
}
module Decode =
let foo =
Decode.object
(fun get ->
{
X = get.Required.Field "x" Decode.int
J = get.Required.Field "j" Decode.value
})
which can decode JSON like:
{
"x": 123,
"j": {
"any": "thing"
}
}