Macros that allow for implicit await in your async code.

Related tags

Database suspend_fn
Overview

suspend fn

Disclaimer: this was mostly made as a proof of concept for the proposal below. I haven't tested if there is a performance cost to this macro.

This crate provides a proc-macro that removes the need for the await keyword. For example:

#[suspend_fn]
fn visit_rustlang() -> Result<(), reqwest::Error> {
    let response = reqwest::get("https://www.rust-lang.org")?;
    let text = response.text()?;
    println!("{}", text);
    text.len(); // sync functions work just fine!
    Ok(())
}

the above code is functionally equivalent to:

async fn visit_rustlang() -> Result<(), reqwest::Error> {
    let response = reqwest::get("https://www.rust-lang.org").await?;
    let text = response.text().await?;
    println!("{}", text);
    text.len(); 
    Ok(())
}

suspend blocks

You can also use the suspend! and suspend_move! macros similarlly to async and async move blocks. Note that these might prompt style warnings, so I recommend placing #![allow(unused_parens)] in the crate root.

#![allow(unused_parens)]
suspend! { 
    let response = reqwest::get("https://www.rust-lang.org")?;
    let text = response.text()?;
    println!("{}", text);
    text.len(); 
}

limitations

Currently, the macro does not work inside other macros. For example:

println!("{}", async_fn());

the above code will raise the following error message:

| println!("{}", async_fn()); 
|                ^^^^^^^^^^  `impl Future` cannot be formatted with the default formatter

for such cases you may simply use .await in the macro yourself.

motivation

In a recent blog post discussing the async cacellation problem, it was argued that async destructors would lead to inconsistencies from a langauge design perspective. This is because the compiler would introduce .await calls for async destructors, making some .await calls implicit and others explicit.

As a way to resolve this conflict, it was proposed the removal of the .await syntax entirely. Although I think this would me great from an ergonomics perspective, I would not like to see such a big breaking change. Alternatively, I propose the addition of a new keyword, analogous to async, for the moment let's use Kotlin's suspend.

Then we could have:

suspend fn function() {
    /* 
        implicit await with implicit calls to async destructors
    */
}
async fn function() {
    /* 
        explicit await with explicit calls to async destructors
    */
}

async {
    /* 
        explicit await with explicit calls to async destructors
    */
}

suspend {
    /* 
        implicit await with implicit calls to async destructors
    */
}

related topics

You might also like...
An Async SDR Runtime for Heterogeneous Architectures

FutureSDR An experimental asynchronous SDR runtime for heterogeneous architectures that is: Extensible: custom buffers (supporting accelerators like G

Rust async runtime based on io-uring.

Monoio A thread-per-core Rust runtime with io_uring. 中文说明 Design Goal As a runtime based on io_uring, Monoio is designed to be the most efficient and

🐚 An async & dynamic ORM for Rust
🐚 An async & dynamic ORM for Rust

SeaORM 🐚 An async & dynamic ORM for Rust SeaORM SeaORM is a relational ORM to help you build web services in Rust with the familiarity of dynamic lan

Quick Pool: High Performance Rust Async Resource Pool

Quick Pool High Performance Rust Async Resource Pool Usage DBCP Database Backend Adapter Version PostgreSQL tokio-postgres qp-postgres Example use asy

Diesel async connection implementation

A async interface for diesel Diesel gets rid of the boilerplate for database interaction and eliminates runtime errors without sacrificing performance

High-level async Cassandra client written in 100% Rust.
High-level async Cassandra client written in 100% Rust.

CDRS tokio CDRS is production-ready Apache Cassandra driver written in pure Rust. Focuses on providing high level of configurability to suit most use

lightweight, async and zero-copy KV Store
lightweight, async and zero-copy KV Store

KipDB 介绍 网络异步交互、零拷贝的轻量级KV数据库 基于PingCAP课程talent-plan 课程地址:https://github.com/pingcap/talent-plan/tree/master/courses/rust 内置多种持久化内核 HashStore: 基于哈希 Sle

Automatically deleted async I/O temporary files in Rust

async-tempfile Provides the TempFile struct, an asynchronous wrapper based on tokio::fs for temporary files that will be automatically deleted when th

Async Lightweight HTTP client using system native library if possible. (Currently under heavy development)

Async Lightweight HTTP Client (aka ALHC) What if we need async but also lightweight http client without using such a large library like reqwest, isahc

Owner
null
Grsql is a great tool to allow you set up your remote sqlite database as service and CRUD(create/read/update/delete) it using gRPC.

Grsql is a great tool to allow you set up your remote sqlite database as service and CRUD (create/ read/ update/ delete) it using gRPC. Why Create Thi

Bruce Yuan 33 Dec 16, 2022
Cassandra DB native client written in Rust language. Find 1.x versions on https://github.com/AlexPikalov/cdrs/tree/v.1.x Looking for an async version? - Check WIP https://github.com/AlexPikalov/cdrs-async

CDRS CDRS is looking for maintainers CDRS is Apache Cassandra driver written in pure Rust. ?? Looking for an async version? async-std https://github.c

Alex Pikalov 338 Jan 1, 2023
📺 Netflix in Rust/ React-TS/ NextJS, Actix-Web, Async Apollo-GraphQl, Cassandra/ ScyllaDB, Async SQLx, Kafka, Redis, Tokio, Actix, Elasticsearch, Influxdb Iox, Tensorflow, AWS

Fullstack Movie Streaming Platform ?? Netflix in RUST/ NextJS, Actix-Web, Async Apollo-GraphQl, Cassandra/ ScyllaDB, Async SQLx, Spark, Kafka, Redis,

null 34 Apr 17, 2023
rust_arango enables you to connect with ArangoDB server, access to database, execute AQL query, manage ArangoDB in an easy and intuitive way, both async and plain synchronous code with any HTTP ecosystem you love.

rust_arango enables you to connect with ArangoDB server, access to database, execute AQL query, manage ArangoDB in an easy and intuitive way, both async and plain synchronous code with any HTTP ecosystem you love.

Foretag 3 Mar 24, 2022
Macros for redis-rs to serialize and deserialize structs automatically

redis-macros Simple macros and wrappers to redis-rs to automatically serialize and deserialize structs with serde. Installation To install it, simply

Daniel Grant 4 Feb 18, 2023
🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, SQLite, and MSSQL.

SQLx ?? The Rust SQL Toolkit Install | Usage | Docs Built with ❤️ by The LaunchBadge team SQLx is an async, pure Rust† SQL crate featuring compile-tim

launchbadge 7.6k Dec 31, 2022
TDS 7.2+ (mssql / Microsoft SQL Server) async driver for rust

Tiberius A native Microsoft SQL Server (TDS) client for Rust. Supported SQL Server versions Version Support level Notes 2019 Tested on CI 2017 Tested

Prisma 189 Dec 25, 2022
Simple, async embedded Rust

Cntrlr - Simple, asynchronous embedded Cntrlr is an all-in-one embedded platform for writing simple asynchronous applications on top of common hobbyis

Branan Riley 11 Jun 3, 2021
An async executor based on the Win32 thread pool API

wae An async executor based on the Win32 thread pool API use futures::channel::oneshot; #[wae::main] async fn main() { let (tx, rx) = oneshot::ch

Raphaël Thériault 10 Dec 10, 2021
Async positioned I/O with io_uring.

uring-positioned-io Fully asynchronized positioned I/O with io_uring. Basic Usage let files = vec![File::open("test.txt").unwrap()]; let context = Uri

Alex Chi 30 Aug 24, 2022