#Alternative to asserts after bool guards

1 messages · Page 1 of 1 (latest)

vital ocean
#

I have parsed my input (path param and a query param). I know that after a bool.guard that this should be ok. so wondering if I can make do without let assert or is that just madatory? also is it not possible to return multiple values rather than return a tuple (the Ok statement)

fn handle_words(req: Request, _ctx: Context, word: String) -> Response {
  use <- wisp.require_method(req, Get)

  let input = {
    use count <- result.try(parse_count(req))
    use word <- result.try(word |> words.from_string)

    Ok(#(count, word))
  }
  use <- bool.guard(input |> result.is_ok, wisp.bad_request())
  let assert Ok(#(count, word)) = input
  /// ...
  wisp.response(200)
}

Thanks

jovial dove
#

You should use result.try for this:

use #(count, word) <- result.try(input)
rough kiln
#

Or pattern match on the result!

jovial dove
#

Oh wait you're not returning a result

#

Probably you want result.lazy_unwrap then

#

Or yeah, just pattern match it

rough kiln
#
fn handle_words(req: Request, _ctx: Context, word: String) -> Response {
  use <- wisp.require_method(req, Get)

  let input = {
    use count <- result.try(parse_count(req))
    use word <- result.try(word |> words.from_string)

    Ok(#(count, word))
  }

  case input {
    Error(_) -> wisp.response(200)
    Ok(#(count, word)) -> ...
  }
}
vital ocean
vital ocean
rough kiln
#

Yeah! And if things start getting unwieldy and feel too nested you can always pull things out in a separate function

vital ocean
#

sep functions sounds like the right approach thank you

#

cause that was the reason for looking to split that block up in the first place

rough kiln
#

Something like this:

fn handle_words(req: Request, _ctx: Context, word: String) -> Response {
  use <- wisp.require_method(req, Get)
  case parse_count_and_words(req, word) {
    Error(_) -> wisp.response(200)
    Ok(#(count, word)) -> wibble_wobble(count, word)
  }
}

fn parse_count_and_words(req: Request, word: String) {
  use count <- result.try(parse_count(req))
  use word <- result.try(word |> words.from_string)
  Ok(#(count, word))
}

fn wibble_wobble() {
  ... 
}
#

Sometimes instead of trying to fit everything into a single use block I prefer giving names to things, it can make things easier to read lucy

vital ocean
#

i'll give that a go thanks. currently refactoring a handler that isn't that large (maybe 20 lines in that input block) but thinking ahead

jovial pebble
#

Generally you should avoid using bools as otherwise you have this problem of having to do unsafe things which the type system can’t help you with

vital ocean
#

seemed as such. with mapping the errors, looks like this would be the right approach right? by using a custom Error type and just pattern matching

parse_count(req) |> result.map_error(fn(_) { BadRequest }),
rough kiln
#

Yeah, also if you’re just replacing the error you could use result.replace_error

vital ocean
#

ohh that is what I was after. yh that makes it a little saner to look at