Hello World works

This commit is contained in:
2026-04-24 22:32:41 +00:00
parent 759497ee70
commit 883d56143f
23 changed files with 447 additions and 487 deletions

View File

@@ -4,9 +4,9 @@ version = "0.1.0"
edition = "2024"
[dependencies]
futures = { version = "0.3.31", default-features = false, features = [
"std",
"async-await",
futures = { version = "0.3.32", default-features = false, features = [
"std",
"async-await",
] }
itertools = "0.14.0"
task-local = "0.1.0"
task-local = "0.1.1"

View File

@@ -1,61 +1,67 @@
use std::cell::RefCell;
use std::fmt;
use std::pin::Pin;
use std::task::Poll;
use std::rc::Rc;
use std::task::{Poll, Waker};
use futures::channel::mpsc::{SendError, UnboundedReceiver, UnboundedSender, unbounded};
use futures::StreamExt;
use futures::future::LocalBoxFuture;
use futures::stream::FuturesUnordered;
use futures::{SinkExt, StreamExt};
pub struct LocalSetController<'a, E> {
sender: UnboundedSender<LocalBoxFuture<'a, Result<(), E>>>,
pub struct SpawnError<T>(T);
impl<T> fmt::Debug for SpawnError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("SpawnError") }
}
pub struct LocalSetState<'a, E> {
waker: Waker,
futures: FuturesUnordered<LocalBoxFuture<'a, Result<(), E>>>,
}
pub struct LocalSetController<'a, E>(Rc<RefCell<LocalSetState<'a, E>>>);
impl<'a, E> LocalSetController<'a, E> {
pub async fn spawn<F: Future<Output = Result<(), E>> + 'a>(
&mut self,
pub fn is_empty(&self) -> bool { self.len() == 0 }
pub fn len(&self) -> usize { self.0.borrow().futures.len() }
pub fn spawn<F: Future<Output = Result<(), E>> + 'a>(&self, fut: F) {
self.try_spawn(fut).unwrap()
}
pub fn try_spawn<F: Future<Output = Result<(), E>> + 'a>(
&self,
fut: F,
) -> Result<(), SendError> {
self.sender.send(Box::pin(fut)).await
) -> Result<(), SpawnError<F>> {
if Rc::strong_count(&self.0) == 1 {
return Err(SpawnError(fut));
}
let g = self.0.borrow_mut();
g.futures.push(Box::pin(fut));
g.waker.wake_by_ref();
Ok(())
}
}
pub fn local_set<'a, E: 'a>()
-> (LocalSetController<'a, E>, impl Future<Output = Result<(), E>> + 'a) {
let (sender, receiver) = unbounded();
let controller = LocalSetController { sender };
let set = LocalSet { receiver, pending: FuturesUnordered::new() };
pub fn local_set<'a, E: 'a>() -> (LocalSetController<'a, E>, LocalSet<'a, E>) {
let state = Rc::new(RefCell::new(LocalSetState {
waker: Waker::noop().clone(),
futures: FuturesUnordered::new(),
}));
let controller = LocalSetController(state.clone());
let set = LocalSet(state);
(controller, set)
}
struct LocalSet<'a, E> {
receiver: UnboundedReceiver<LocalBoxFuture<'a, Result<(), E>>>,
pending: FuturesUnordered<LocalBoxFuture<'a, Result<(), E>>>,
}
pub struct LocalSet<'a, E>(Rc<RefCell<LocalSetState<'a, E>>>);
impl<E> Future for LocalSet<'_, E> {
type Output = Result<(), E>;
fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
let mut any_pending = false;
loop {
match this.receiver.poll_next_unpin(cx) {
Poll::Ready(Some(fut)) => this.pending.push(fut),
Poll::Ready(None) => break,
Poll::Pending => {
any_pending = true;
break;
},
}
let ctl_dropped = 1 == Rc::strong_count(&self.0);
let mut this = self.0.borrow_mut();
if !ctl_dropped {
this.waker.clone_from(cx.waker());
}
loop {
match this.pending.poll_next_unpin(cx) {
Poll::Ready(Some(Err(e))) => return Poll::Ready(Err(e)),
Poll::Ready(Some(Ok(()))) => continue,
Poll::Ready(None) => break,
Poll::Pending => {
any_pending = true;
break;
},
}
match this.futures.poll_next_unpin(cx) {
Poll::Ready(Some(Err(e))) => Poll::Ready(Err(e)),
Poll::Ready(None) if ctl_dropped => Poll::Ready(Ok(())),
_ => Poll::Pending,
}
if any_pending { Poll::Pending } else { Poll::Ready(Ok(())) }
}
}