1use std::pin::Pin;
4use std::task::{Context, Poll, Waker};
5
6pub struct SyncRuntime;
13
14impl SyncRuntime {
15 pub fn block_on<F>(mut f: F) -> F::Output
16 where
17 F: Future,
18 {
19 let mut f = unsafe { Pin::new_unchecked(&mut f) };
20
21 let mut ctx = Context::from_waker(Waker::noop());
22
23 let Poll::Ready(val) = f.as_mut().poll(&mut ctx) else {
24 unreachable!("Future should not be pending in sync context");
25 };
26
27 val
28 }
29}
30
31pub fn block_on<F>(f: F) -> F::Output
35where
36 F: Future,
37{
38 SyncRuntime::block_on(f)
39}
40
41#[cfg(test)]
42mod test {
43
44 use pretty_assertions::assert_eq;
45
46 use super::*;
47
48 #[test]
49 fn test_should_execute_async_code_in_sync_context() {
50 let result = SyncRuntime::block_on(async_fn());
51 assert_eq!(result, 42);
52 }
53
54 #[test]
55 fn test_should_execute_async_code_in_sync_context_with_block_on() {
56 let result = block_on(async_fn());
57 assert_eq!(result, 42);
58 }
59
60 async fn async_fn() -> i32 {
61 42
62 }
63}