Skip to content

Instantly share code, notes, and snippets.

@buffalojoec
Last active August 16, 2023 18:36
Show Gist options
  • Save buffalojoec/3dffc2d98b84f166d2fae0db21c31ffd to your computer and use it in GitHub Desktop.
Save buffalojoec/3dffc2d98b84f166d2fae0db21c31ffd to your computer and use it in GitHub Desktop.
Sharing closure-fed library functions across async and sync
/// Scenario #1:
mod not_fut{
/// A lib function designed to take a closure that returns a `String`
fn lib_function<F>(get_account_data_fn: F) -> String
where
F: Fn(u8) -> String,
{
let account_data = get_account_data_fn(42);
println!("Account data: {}", account_data);
account_data
}
/// A sample async function, such as an RPC client call
async fn some_async_fn(num: u8) -> String {
num.to_string()
}
/// This is the async context, where we want to call the lib function
async fn async_context() {
// [Error]
// `await` is only allowed inside `async` functions and blocks
let _: String = lib_function(|num| { some_async_fn(num).await });
// [Error]
// async closures are unstable
// see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
let _: String = lib_function(async |num| { some_async_fn(num).await });
}
/// This is the sync context, where we want to call the lib function
fn sync_context<F, Fut>() {
// [Ok]
let _: String = lib_function(|num| { num.to_string() });
}
}
/// Scenario #2:
mod with_fut{
use std::future::Future;
/// A lib function designed to take a closure that returns a `Fut<String>`
fn lib_function<F, Fut>(get_account_data_fn: F) -> Fut
where
F: Fn(u8) -> Fut,
Fut: Future<Output = String>,
{
let account_data = get_account_data_fn(42);
// [Error]
// `Fut` doesn't implement `std::fmt::Display`
println!("Account data: {}", account_data);
account_data
}
/// A sample async function, such as an RPC client call
async fn some_async_fn(num: u8) -> String {
num.to_string()
}
/// This is the async context, where we want to call the lib function
async fn async_context() {
// [Ok]
let _: String = lib_function(some_async_fn).await;
}
/// This is the sync context, where we want to call the lib function
fn sync_context<F, Fut>() {
// [Error]
// `String` is not a future
let _: String = lib_function(|num| { num.to_string() });
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment