Quantcast
Channel: ReScript Forum - Latest posts
Viewing all articles
Browse latest Browse all 2592

Oh no, we're toast because of PPX usage

$
0
0

Several options here. OTOH just like @tsnobip says, migrating to Spice might be an option? GitHub - green-labs/ppx_spice: ReScript PPX which generates the JSON (de)serializers

Anyway, bear with me with the technical details, but in ReScript v11.1 there’s a flag you can use to reprint a source file and expand a certain PPX while doing it. You need to call the underlying compiler (bsc) directly. Here’s an example:

// Tst.res
@decco
type myType = {
  name: string,
  age: option<int>,
}

Command: ./node_modules/rescript/bsc -ppx node_modules/decco/ppx -bs-no-builtin-ppx -reprint-source src/Tst.res

This will output the above source, but with the PPX expanded:

@decco
type myType = {
  name: string,
  age: option<int>,
}
@ocaml.warning(@reason.raw_literal("-39") "-39")
let myType_encode = v =>
  (
    v =>
      [("name", Decco.stringToJson(v.name)), ("age", Decco.optionToJson(Decco.intToJson)(v.age))]
      |> Js.Dict.fromArray
      |> Js.Json.object_
  )(v)
@ocaml.warning(@reason.raw_literal("-4") "-4") @ocaml.warning(@reason.raw_literal("-39") "-39")
and myType_decode = v =>
  (
    v =>
      switch Js.Json.classify(v) {
      | @explicit_arity Js.Json.JSONObject(dict) =>
        switch (Js.Dict.get(dict, "name")->Belt.Option.getWithDefault)(
          Js.Json.null,
        ) |> Decco.stringFromJson {
        | @explicit_arity Belt.Result.Ok(name) =>
          switch (Js.Dict.get(dict, "age")->Belt.Option.getWithDefault)(
            Js.Json.null,
          ) |> Decco.optionFromJson(Decco.intFromJson) {
          | @explicit_arity Belt.Result.Ok(age) => @explicit_arity Belt.Result.Ok({name, age})
          | @explicit_arity Belt.Result.Error(e: Decco.decodeError) =>
            @explicit_arity
            Belt.Result.Error({...e, path: \"^"(@reason.raw_literal(".") ".", \"^"("age", e.path))})
          }
        | @explicit_arity Belt.Result.Error(e: Decco.decodeError) =>
          @explicit_arity
          Belt.Result.Error({...e, path: \"^"(@reason.raw_literal(".") ".", \"^"("name", e.path))})
        }
      | _ => Decco.error(@reason.raw_literal("Not an object") "Not an object", v)
      }
  )(v)

This is a way to “eject” from a PPX. But, there’s obviously no guarantees that the code the PPX generates will compile, so you might need to figure out some sort of migration/cleanup script if you go this route (https://comby.dev is excellent for this).


Viewing all articles
Browse latest Browse all 2592

Trending Articles