代码之家  ›  专栏  ›  技术社区  ›  Bertrand

将json字段转换为reasonml变量

  •  2
  • Bertrand  · 技术社区  · 7 年前

    我有一个包含字段的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 反对 String 这是我的一部分 periodVariant ,但我不知道如何实现我想要的。

    2 回复  |  直到 7 年前
        1
  •  5
  •   glennsl Namudon'tdie    7 年前

    这是什么 either 是为了。随着 map 方便地“提升”现有解码器到您的变体类型。

    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))
      ));
    
        2
  •  2
  •   franky    7 年前

    我知道你在使用bs-json,所以一种方法是利用 Json.Decode.optional 收益率 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 . 我不确定这是不是惯用的方法!