How to simplify nested switches?

I’m currently trying out rescript and I was wondering if there is something like a .bind method or syntactic sugar to simplify nested switches where values depend on one another?

switch c->Context.req->HonoRequest.param("id") {
| Some(id) =>
  switch await Environment.db->Channel.Repo.select(id) {
  | Some(channel) => {
    let sandbox = channel.sandboxId->Sandbox.findContainerById
    let prompt = promptSchema->SuryStandardSchema.valid(c, "json")
    await Sandbox.prompt(sandbox, prompt.message)
    c->Context.json({"message": "huuray"})
  }
  | None => c->Context.text("not found", ~status=404)
  }
| None => c->Context.text("not found", ~status=404)
}

The new let? feature can help a lot with this. Your code using that feature instead:

let value = {
  let? Some(id) = c->Context.req->HonoRequest.param("id")
  let? Some(channel) = await Environment.db->Channel.Repo.select(id)
  let sandbox = channel.sandboxId->Sandbox.findContainerById
  let prompt = promptSchema->SuryStandardSchema.valid(c, "json")
  await Sandbox.prompt(sandbox, prompt.message)
  Some(c->Context.json({"message": "huuray"}))
}

value->Option.getOr(c->Context.text("not found", ~status=404))

Note that let value = { is in a block, because let? expects the you to return either option or result from the current block, and you want to remap it to that None default value you had.

3 Likes

Don’t forget to enable it in rescript.json as it is still an experimental feature:

"experimental-features": {
  "LetUnwrap": true
},
2 Likes