Skip to content
This repository was archived by the owner on Mar 3, 2020. It is now read-only.
This repository was archived by the owner on Mar 3, 2020. It is now read-only.

Mixing early returns with async_blocks #107

@illicitonion

Description

@illicitonion

I realise that this isn't really about async/await itself, but using it in surrounding code made me question my instincts, so I figured I'd open a discussion...

I want to write some code along the lines of:

fn foo(&self) -> impl Future<...> {
  if let Some(early_value) = self.check() {
    // Doesn't compile because Ok is a Result, but function returns an `impl Future`.
    // Need to return a futures::future::ok(early_value) instead.
    return Ok(early_value);
  }

  // Doesn't compile because the ? operator can't be used in a function which returns an impl Future.
  // Need to explicitly match and early-return instead.
  let request = self.prepare_request()?;

  // Clone value out because borrows aren't allowed in async_blocks.
  let client = self.client.clone();

  async_block! {
    let response = await!(client.make_request(request));
    await!(parse(response))
  }
}

There are three big things that stop me from being able to do this today; the two things commented on in the code, and that my function returns an impl Future, but after making the two changes in the comments, I'm no longer returning one unique anonymous Future type, so I need to Box everything up rather than returning an impl Trait.

My instinct is that my async_block should be as short as possible, because minimising the scope where the reader needs to consider asynchrony feels good. But if I'd moved the lines before the client cloning as-is into the async_block, the code would compile fine (modulo theself borrows), because the async_block itself does effectively return a Result.

Is my instinct to minimise the size of aync_blocks wrong? Is there a more ergonomic way of doing what I'm doing without enlarging the async_block?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions