Skip to main content

dope_fiber/
lib.rs

1//! Driver-scoped cooperative async built by rustc.
2//! [`Fiber`](abi::Fiber) is the application async ABI: [`fiber!`] and [`fiber_fn`] retain Rust's async language and rustc state machines. Application awaits accept a `Fiber` bound to the same driver scope; immediately awaited non-move `async` scopes share the enclosing brand and budget. Standard future and waker machinery are a sealed compiler bridge, never an interoperability surface.
3//! The bridge preserves exact lifetime and scope identity and the native future's layout without heap allocation or synchronization. A stack-local frame delegates the admitted initial descent; subsequent awaits consume application credits. For nesting depth D and budget B, traversal is bounded by O(B × D) under the fibers' cooperative-work contract. Scheduling, wakeups, cancellation, and typed failures stay in the driver context; standalone polling uses [`abi::Task`] to retain completion ownership.
4
5use dope::{core, manifold, runtime};
6use runtime::{
7    executor,
8    executor::{drive, session},
9};
10
11pub mod abi;
12pub mod context;
13pub mod file;
14pub mod net;
15pub mod reply;
16pub mod task;
17pub mod wait;
18
19pub use dope_gen::{fiber, fiber_fn};
20
21pub trait BlockOn<'d> {
22    fn block_on<F>(&mut self, fiber: F) -> Result<F::Output, drive::Error>
23    where
24        F: abi::Fiber<'d>;
25}
26
27impl<'app, 'life: 'app, 'd: 'life, D, Q> BlockOn<'d> for session::App<'app, 'life, 'd, D, Q>
28where
29    D: executor::raw::App<'d>,
30    Q: executor::Startup,
31{
32    fn block_on<F>(&mut self, fiber: F) -> Result<F::Output, drive::Error>
33    where
34        F: abi::Fiber<'d>,
35    {
36        use task::done;
37
38        self.drive(done::Once::new(fiber))
39    }
40}
41
42impl<'app, 'life: 'app, 'd: 'life, D, Q> BlockOn<'d>
43    for runtime::signal::App<'_, 'app, 'life, 'd, D, Q>
44where
45    D: executor::raw::App<'d>,
46    Q: executor::Startup,
47{
48    fn block_on<F>(&mut self, fiber: F) -> Result<F::Output, drive::Error>
49    where
50        F: abi::Fiber<'d>,
51    {
52        self.drive(task::done::Once::new(fiber))
53    }
54}
55
56impl<'d> abi::Fiber<'d> for &mut runtime::signal::Wait<'_, 'd> {
57    type Output = Result<(), runtime::signal::Error>;
58
59    fn poll(call: context::PollCall<'_, '_, 'd, Self>) -> std::task::Poll<Self::Output> {
60        let (this, context) = call.into_parts();
61        this.get_mut().poll(context.as_ref().completion())
62    }
63}