将 JSON 字段转换为 ReasonML 变体
Convert JSON field to ReasonML variant
我有一个 JSON 结构,其中包含一个可以是对象或字符串的字段 period
。
我已经在我的代码中准备好变体,并且工作正常:
type period = {
start: string,
end_: string,
};
type periodVariant =
| String(string)
| Period(period);
问题是当我尝试将输入 JSON 转换为变体类型时:我根本不知道该怎么做。
这是我的尝试:
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),
})
};
};
现在,这当然行不通了,因为我正在尝试将仍然属于 Js.Json.t
类型的内容与属于 periodVariant
的 String
进行匹配,但是我不知道如何实现我想要的。
我看到你正在使用 bs-json 所以一种方法是利用 Json.Decode.optional
returns None
如果解码失败。例如:
type period = {
start: string,
end_: string,
};
type periodVariant =
| String(string)
| Period(period);
let periodVariantDecode = json => {
let periodString = json |> Json.Decode.(optional(string));
switch (periodString) {
| Some(periodString) => String(periodString)
| None =>
let periodObj =
Json.Decode.{
start: json |> field("start", string),
end_: json |> field("end", string),
};
Period(periodObj);
};
};
编译时 periodVariantDecode
应该是 Js.Json.t => periodVariant
类型。我不确定这是否是惯用的方式!
这就是 either
is for. Along with map
方便地 "lift" 您的变体类型的现有解码器。
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))
));
我有一个 JSON 结构,其中包含一个可以是对象或字符串的字段 period
。
我已经在我的代码中准备好变体,并且工作正常:
type period = {
start: string,
end_: string,
};
type periodVariant =
| String(string)
| Period(period);
问题是当我尝试将输入 JSON 转换为变体类型时:我根本不知道该怎么做。 这是我的尝试:
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),
})
};
};
现在,这当然行不通了,因为我正在尝试将仍然属于 Js.Json.t
类型的内容与属于 periodVariant
的 String
进行匹配,但是我不知道如何实现我想要的。
我看到你正在使用 bs-json 所以一种方法是利用 Json.Decode.optional
returns None
如果解码失败。例如:
type period = {
start: string,
end_: string,
};
type periodVariant =
| String(string)
| Period(period);
let periodVariantDecode = json => {
let periodString = json |> Json.Decode.(optional(string));
switch (periodString) {
| Some(periodString) => String(periodString)
| None =>
let periodObj =
Json.Decode.{
start: json |> field("start", string),
end_: json |> field("end", string),
};
Period(periodObj);
};
};
编译时 periodVariantDecode
应该是 Js.Json.t => periodVariant
类型。我不确定这是否是惯用的方式!
这就是 either
is for. Along with map
方便地 "lift" 您的变体类型的现有解码器。
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))
));