#[repr(C)]pub struct StackFuture<'a, T, const STACK_SIZE: usize> { /* private fields */ }
Expand description
A wrapper that stores a future in space allocated by the container
Often this space comes from the calling function’s stack, but it could just as well come from some other allocation.
A StackFuture
can be used to emulate async functions in dyn Trait objects.
For example:
trait PseudoAsyncTrait {
fn do_something(&self) -> StackFuture<'_, (), { 512 }>;
}
impl PseudoAsyncTrait for i32 {
fn do_something(&self) -> StackFuture<'_, (), { 512 }> {
StackFuture::from(async {
// function body goes here
})
}
}
async fn use_dyn_async_trait(x: &dyn PseudoAsyncTrait) {
x.do_something().await;
}
async fn call_with_dyn_async_trait() {
use_dyn_async_trait(&42).await;
}
This example defines PseudoAsyncTrait
with a single method do_something
.
The do_something
method can be called as if it were declared as
async fn do_something(&self)
. To implement do_something
, the easiest thing
to do is to wrap the body of the function in StackFuture::from(async { ... })
,
which creates an anonymous future for the body and stores it in a StackFuture
.
Because StackFuture
does not know the size of the future it wraps, the maximum
size of the future must be specified in the STACK_SIZE
parameter. In the example
here, we’ve used a stack size of 512, which is probably much larger than necessary
but would accommodate many futures besides the simple one we’ve shown here.
StackFuture
ensures when wrapping a future that enough space is available, and
it also respects any alignment requirements for the wrapped future. Note that the
wrapped future’s alignment must be less than or equal to that of the overall
StackFuture
struct.
Implementations§
source§impl<'a, T, const STACK_SIZE: usize> StackFuture<'a, T, STACK_SIZE>
impl<'a, T, const STACK_SIZE: usize> StackFuture<'a, T, STACK_SIZE>
sourcepub fn from<F>(future: F) -> Self
pub fn from<F>(future: F) -> Self
Creates a StackFuture
from an existing future
See the documentation on StackFuture
for examples of how to use this.
The size and alignment requirements are statically checked, so it is a compiler error
to use this with a future that does not fit within the StackFuture
’s size and
alignment requirements.
The following example illustrates a compile error for a future that is too large.
// Fails because the future contains a large array and is therefore too big to fit in
// a 16-byte `StackFuture`.
let f = StackFuture::<_, { 16 }>::from(async {
let x = [0u8; 4096];
async {}.await;
println!("{}", x.len());
});
The example below illustrates a compiler error for a future whose alignment is too large.
#[derive(Debug)]
#[repr(align(256))]
struct BigAlignment(usize);
// Fails because the future contains a large array and is therefore too big to fit in
// a 16-byte `StackFuture`.
let f = StackFuture::<_, { 16 }>::from(async {
let x = BigAlignment(42);
async {}.await;
println!("{x:?}");
});
sourcepub fn try_from<F>(future: F) -> Result<Self, IntoStackFutureError<F>>
pub fn try_from<F>(future: F) -> Result<Self, IntoStackFutureError<F>>
Attempts to create a StackFuture
from an existing future
If the StackFuture
is not large enough to hold future
, this function returns an
Err
with the argument future
returned to you.
Panics
If we cannot satisfy the alignment requirements for F
, this function will panic.
sourcepub fn from_or_box<F>(future: F) -> Self
pub fn from_or_box<F>(future: F) -> Self
Creates a StackFuture from the given future, boxing if necessary
This version will succeed even if the future is larger than STACK_SIZE
. If the future
is too large, from_or_box
will allocate a Box
on the heap and store the resulting
boxed future in the StackFuture
.
The same thing also happens if the wrapped future’s alignment is larger than StackFuture’s alignment.
This function requires the “alloc” crate feature.
sourcepub const fn has_space_for<F>() -> bool
pub const fn has_space_for<F>() -> bool
Determines whether this StackFuture
can hold a value of type F
sourcepub const fn has_space_for_val<F>(_: &F) -> bool
pub const fn has_space_for_val<F>(_: &F) -> bool
Determines whether this StackFuture
can hold the referenced value
sourcepub const fn has_alignment_for<F>() -> bool
pub const fn has_alignment_for<F>() -> bool
Determines whether this StackFuture
’s alignment is compatible with the
type F
.
sourcepub const fn has_alignment_for_val<F>(_: &F) -> bool
pub const fn has_alignment_for_val<F>(_: &F) -> bool
Determines whether this StackFuture
’s alignment is compatible with the
referenced value.