File size: 1,435 Bytes
9552aa0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use pin_project_lite::pin_project;
use std::{
  future::Future,
  pin::Pin,
  task::{Context, Poll},
};
use tokio::runtime::Handle;

pin_project! {
    /// A future that executes within a specific Tokio runtime.
    ///
    /// This struct ensures that the wrapped future (`fut`) is polled within the context of the provided Tokio runtime handle (`runtime`).
    pub struct WithRuntime<F> {
        runtime: Handle,
        #[pin]
        fut: F,
    }
}

impl<F> WithRuntime<F> {
  /// Creates a new `WithRuntime` instance.
  ///
  /// # Parameters
  ///
  /// - `runtime`: A `Handle` to the Tokio runtime in which the future should be executed.
  /// - `fut`: The future to be executed within the specified runtime.
  ///
  /// # Returns
  ///
  /// A `WithRuntime` object encapsulating the provided runtime handle and future.
  pub fn new(runtime: Handle, fut: F) -> Self {
    Self { runtime, fut }
  }
}

impl<F> Future for WithRuntime<F>
where
  F: Future,
{
  type Output = F::Output;

  /// Polls the wrapped future within the context of the specified Tokio runtime.
  ///
  /// # Parameters
  ///
  /// - `ctx`: The current task context.
  ///
  /// # Returns
  ///
  /// A `Poll` indicating the state of the wrapped future (`Pending` or `Ready`).
  fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
    let this = self.project();
    let _guard = this.runtime.enter();
    this.fut.poll(ctx)
  }
}