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?
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.
Sometimes let? can get annoying, specially when going between results and options. So I often use a little AsyncOption module (and a similar one for Result) so maybe it’ll help you too.
AsyncOption:
And your code can look like this:
let value = (await c->Context.req->HonoRequest.param("id")
->AsyncOption.fromOption
->AsyncOption.flatMap(id => Environment.db->Channel.Repo.select(id))
->AsyncOption.map(async 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"})
}))
->Option.getOr(c->Context.text("not found", ~status=404))