abol_rt/lib.rs
1use core::future::Future;
2use core::pin::Pin;
3use core::task::{Context, Poll};
4use std::net::SocketAddr;
5
6use async_trait::async_trait;
7
8use crate::net::AsyncUdpSocket;
9pub mod net;
10/// A trait defining the asynchronous execution and networking environment.
11///
12/// This trait abstracts over different async runtimes (e.g., Tokio, Smol),
13/// allowing the server logic to remain independent of the underlying event loop.
14///
15/// Implementers must ensure that both the socket and executor types are
16/// compatible with the chosen async reactor.
17#[async_trait]
18pub trait Runtime: Send + Sync + 'static {
19 /// The asynchronous UDP socket type associated with this runtime.
20 type Socket: AsyncUdpSocket;
21
22 /// The task executor used to spawn background futures.
23 type Executor: Executor;
24
25 /// Returns a reference to the runtime's task executor.
26 ///
27 /// This is used by the server to spawn concurrent packet-handling tasks.
28 fn executor(&self) -> &Self::Executor;
29
30 /// Binds a new asynchronous UDP socket to the specified address.
31 ///
32 /// # Errors
33 ///
34 /// Returns an [`std::io::Result`] if the socket cannot be bound,
35 /// typically due to the address being in use or invalid permissions.
36 async fn bind(&self, addr: SocketAddr) -> std::io::Result<Self::Socket>;
37}
38pub trait Executor {
39 /// Place the future into the executor to be run.
40 fn execute<Fut>(&self, fut: Fut)
41 where
42 Fut: std::future::Future<Output = ()> + Send + 'static;
43}
44pub struct YieldNow {
45 yielded: bool,
46}
47
48impl YieldNow {
49 pub fn new() -> Self {
50 Self { yielded: false }
51 }
52}
53impl Default for YieldNow {
54 fn default() -> Self {
55 Self::new()
56 }
57}
58
59impl Future for YieldNow {
60 type Output = ();
61 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
62 if self.yielded {
63 Poll::Ready(())
64 } else {
65 self.yielded = true;
66 cx.waker().wake_by_ref();
67 Poll::Pending
68 }
69 }
70}