I have a JSON structure that contains a field period
that can either be an object or a string.
I already have the variant ready in my code, and it's working fine:
type period = {
start: string,
end_: string,
};
type periodVariant =
| String(string)
| Period(period);
The problem is when I try to cast the input JSON to the variant type: I simply don't know how to do that. Here's what my attempt looks like:
let periodVariantDecode = (json: Js.Json.t): periodVariant => {
switch(json) {
| String(string) => String(Json.Decode.string(string))
| period => Period(Json.Decode.{
start: period |> field("start", string),
end_: period |> field("end", string),
})
};
};
Now, of course that doesn't work because I'm trying to match something that is still of type Js.Json.t
against String
which is part of my periodVariant
, but I don't know how to achieve what I want.
This is what either
is for. Along with map
to conveniently "lift" an existing decoder to your variant type.
type period = {
start: string,
end_: string,
};
type periodVariant =
| String(string)
| Period(period);
let period = json =>
Json.Decode.{
start: json |> field("start", string),
end_: json |> field("end", string),
};
let periodVariantDecode =
Json.Decode.(either(
period |> map(p => Period(p)),
string |> map(s => String(s))
));