updated all deps

migrated away from paste and async-std
This commit is contained in:
2025-09-03 18:42:54 +02:00
parent 7031f3a7d8
commit 088cb6a247
44 changed files with 569 additions and 456 deletions

View File

@@ -7,11 +7,9 @@ use std::pin::Pin;
use std::rc::Rc;
use ahash::HashMap;
use async_std::io::{Read, Write};
use async_std::stream;
use dyn_clone::{DynClone, clone_box};
use futures::future::LocalBoxFuture;
use futures::{FutureExt, StreamExt};
use futures::{AsyncRead, AsyncWrite, FutureExt, StreamExt, stream};
use orchid_api_derive::Coding;
use orchid_api_traits::{Coding, Decode, Encode, Request, enc_vec};
use orchid_base::clone;
@@ -157,8 +155,8 @@ trait_set! {
trait AtomReqCb<A> = for<'a> Fn(
&'a A,
SysCtx,
Pin<&'a mut dyn Read>,
Pin<&'a mut dyn Write>,
Pin<&'a mut dyn AsyncRead>,
Pin<&'a mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, ()>
}
@@ -173,17 +171,19 @@ impl<A: AtomCard> MethodSetBuilder<A> {
assert!(!M::NAME.is_empty(), "AtomMethod::NAME cannoot be empty");
self.handlers.push((
M::NAME,
Rc::new(move |a: &A, ctx: SysCtx, req: Pin<&mut dyn Read>, rep: Pin<&mut dyn Write>| {
async { Supports::<M>::handle(a, ctx, M::decode(req).await).await.encode(rep).await }
.boxed_local()
}),
Rc::new(
move |a: &A, ctx: SysCtx, req: Pin<&mut dyn AsyncRead>, rep: Pin<&mut dyn AsyncWrite>| {
async { Supports::<M>::handle(a, ctx, M::decode(req).await).await.encode(rep).await }
.boxed_local()
},
),
));
self
}
pub async fn pack(&self, ctx: SysCtx) -> MethodSet<A> {
MethodSet {
handlers: stream::from_iter(self.handlers.iter())
handlers: stream::iter(self.handlers.iter())
.then(|(k, v)| {
clone!(ctx; async move {
(Sym::parse(k, ctx.i()).await.unwrap(), v.clone())
@@ -204,8 +204,8 @@ impl<A: AtomCard> MethodSet<A> {
atom: &'a A,
ctx: SysCtx,
key: Sym,
req: Pin<&'a mut dyn Read>,
rep: Pin<&'a mut dyn Write>,
req: Pin<&'a mut dyn AsyncRead>,
rep: Pin<&'a mut dyn AsyncWrite>,
) -> bool {
match self.handlers.get(&key) {
None => false,
@@ -286,14 +286,14 @@ pub trait AtomDynfo: 'static {
&'a self,
ctx: AtomCtx<'a>,
key: Sym,
req: Pin<&'b mut dyn Read>,
rep: Pin<&'c mut dyn Write>,
req: Pin<&'b mut dyn AsyncRead>,
rep: Pin<&'c mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, bool>;
fn command<'a>(&'a self, ctx: AtomCtx<'a>) -> LocalBoxFuture<'a, OrcRes<Option<GExpr>>>;
fn serialize<'a, 'b: 'a>(
&'a self,
ctx: AtomCtx<'a>,
write: Pin<&'b mut dyn Write>,
write: Pin<&'b mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, Option<Vec<Expr>>>;
fn deserialize<'a>(
&'a self,

View File

@@ -6,11 +6,10 @@ use std::ops::Deref;
use std::pin::Pin;
use std::sync::atomic::AtomicU64;
use async_lock::{RwLock, RwLockReadGuard};
use async_once_cell::OnceCell;
use async_std::io::{Read, Write};
use async_std::sync::{RwLock, RwLockReadGuard};
use futures::FutureExt;
use futures::future::{LocalBoxFuture, ready};
use futures::{AsyncRead, AsyncWrite, FutureExt};
use itertools::Itertools;
use memo_map::MemoMap;
use never::Never;
@@ -105,8 +104,8 @@ impl<T: OwnedAtom> AtomDynfo for OwnedAtomDynfo<T> {
&'a self,
AtomCtx(_, id, ctx): AtomCtx,
key: Sym,
req: Pin<&'b mut dyn Read>,
rep: Pin<&'c mut dyn Write>,
req: Pin<&'b mut dyn AsyncRead>,
rep: Pin<&'c mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, bool> {
Box::pin(async move {
let a = AtomReadGuard::new(id.unwrap(), &ctx).await;
@@ -126,7 +125,7 @@ impl<T: OwnedAtom> AtomDynfo for OwnedAtomDynfo<T> {
fn serialize<'a, 'b: 'a>(
&'a self,
AtomCtx(_, id, ctx): AtomCtx<'a>,
mut write: Pin<&'b mut dyn Write>,
mut write: Pin<&'b mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, Option<Vec<Expr>>> {
Box::pin(async move {
let id = id.unwrap();
@@ -241,7 +240,7 @@ pub trait OwnedAtom: Atomic<Variant = OwnedVariant> + Any + Clone + 'static {
fn serialize(
&self,
ctx: SysCtx,
write: Pin<&mut (impl Write + ?Sized)>,
write: Pin<&mut (impl AsyncWrite + ?Sized)>,
) -> impl Future<Output = Self::Refs> {
assert_serializable::<Self>();
async { panic!("Either implement serialize or set Refs to Never for {}", type_name::<Self>()) }
@@ -263,7 +262,7 @@ fn assert_serializable<T: OwnedAtom>() {
pub trait DynOwnedAtom: 'static {
fn atom_tid(&self) -> TypeId;
fn as_any_ref(&self) -> &dyn Any;
fn encode<'a>(&'a self, buffer: Pin<&'a mut dyn Write>) -> LocalBoxFuture<'a, ()>;
fn encode<'a>(&'a self, buffer: Pin<&'a mut dyn AsyncWrite>) -> LocalBoxFuture<'a, ()>;
fn dyn_call_ref(&self, arg: Expr) -> LocalBoxFuture<'_, GExpr>;
fn dyn_call(self: Box<Self>, arg: Expr) -> LocalBoxFuture<'static, GExpr>;
fn dyn_command(self: Box<Self>, ctx: SysCtx) -> LocalBoxFuture<'static, OrcRes<Option<GExpr>>>;
@@ -272,13 +271,13 @@ pub trait DynOwnedAtom: 'static {
fn dyn_serialize<'a>(
&'a self,
ctx: SysCtx,
sink: Pin<&'a mut dyn Write>,
sink: Pin<&'a mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, Option<Vec<Expr>>>;
}
impl<T: OwnedAtom> DynOwnedAtom for T {
fn atom_tid(&self) -> TypeId { TypeId::of::<T>() }
fn as_any_ref(&self) -> &dyn Any { self }
fn encode<'a>(&'a self, buffer: Pin<&'a mut dyn Write>) -> LocalBoxFuture<'a, ()> {
fn encode<'a>(&'a self, buffer: Pin<&'a mut dyn AsyncWrite>) -> LocalBoxFuture<'a, ()> {
async { self.val().await.as_ref().encode(buffer).await }.boxed_local()
}
fn dyn_call_ref(&self, arg: Expr) -> LocalBoxFuture<'_, GExpr> {
@@ -299,7 +298,7 @@ impl<T: OwnedAtom> DynOwnedAtom for T {
fn dyn_serialize<'a>(
&'a self,
ctx: SysCtx,
sink: Pin<&'a mut dyn Write>,
sink: Pin<&'a mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, Option<Vec<Expr>>> {
match TypeId::of::<Never>() == TypeId::of::<<Self as OwnedAtom>::Refs>() {
true => ready(None).boxed_local(),

View File

@@ -3,9 +3,8 @@ use std::future::Future;
use std::pin::Pin;
use async_once_cell::OnceCell;
use async_std::io::{Read, Write};
use futures::FutureExt;
use futures::future::LocalBoxFuture;
use futures::{AsyncRead, AsyncWrite, FutureExt};
use orchid_api_traits::{Coding, enc_vec};
use orchid_base::error::OrcRes;
use orchid_base::format::FmtUnit;
@@ -59,8 +58,8 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
&'a self,
AtomCtx(buf, _, sys): AtomCtx<'a>,
key: Sym,
req: Pin<&'m1 mut dyn Read>,
rep: Pin<&'m2 mut dyn Write>,
req: Pin<&'m1 mut dyn AsyncRead>,
rep: Pin<&'m2 mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, bool> {
Box::pin(async move {
let ms = self.ms.get_or_init(self.msbuild.pack(sys.clone())).await;
@@ -76,7 +75,7 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
fn serialize<'a, 'b: 'a>(
&'a self,
ctx: AtomCtx<'a>,
write: Pin<&'b mut dyn Write>,
write: Pin<&'b mut dyn AsyncWrite>,
) -> LocalBoxFuture<'a, Option<Vec<Expr>>> {
Box::pin(async {
T::decode(Pin::new(&mut &ctx.0[..])).await.encode(write).await;

View File

@@ -3,10 +3,10 @@ use std::marker::PhantomData;
use std::pin::Pin;
use std::rc::Rc;
use async_std::channel::{Receiver, RecvError, Sender, bounded};
use async_std::sync::Mutex;
use futures::channel::mpsc::{Receiver, Sender, channel};
use futures::future::Fuse;
use futures::{FutureExt, select};
use futures::lock::Mutex;
use futures::{FutureExt, SinkExt, StreamExt, select};
use never::Never;
use orchid_base::error::OrcRes;
@@ -22,20 +22,20 @@ enum Command {
}
struct BuilderCoroutineData {
work: Mutex<Fuse<Pin<Box<dyn Future<Output = GExpr>>>>>,
work: Fuse<Pin<Box<dyn Future<Output = GExpr>>>>,
cmd_recv: Receiver<Command>,
}
#[derive(Clone)]
struct BuilderCoroutine(Rc<BuilderCoroutineData>);
struct BuilderCoroutine(Rc<Mutex<BuilderCoroutineData>>);
impl BuilderCoroutine {
pub async fn run(self) -> GExpr {
let cmd = {
let mut work = self.0.work.lock().await;
let this = &mut *self.0.lock().await;
select! {
ret_val = &mut *work => { return ret_val },
cmd_res = self.0.cmd_recv.recv().fuse() => match cmd_res {
Ok(cmd) => cmd,
Err(RecvError) => return (&mut *work).await
ret_val = &mut this.work => { return ret_val },
cmd_res = this.cmd_recv.next().fuse() => match cmd_res {
Some(cmd) => cmd,
None => return (&mut this.work).await
},
}
};
@@ -65,17 +65,17 @@ impl Atomic for Replier {
impl OwnedAtom for Replier {
type Refs = Never;
async fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(()) }
async fn call(self, arg: Expr) -> GExpr {
async fn call(mut self, arg: Expr) -> GExpr {
let _ = self.reply.send(arg).await;
self.builder.run().await
}
}
pub async fn exec<R: ToExpr>(f: impl for<'a> AsyncFnOnce(ExecHandle<'a>) -> R + 'static) -> GExpr {
let (cmd_snd, cmd_recv) = bounded(1);
let (cmd_snd, cmd_recv) = channel(0);
let work =
async { f(ExecHandle(cmd_snd, PhantomData)).await.to_expr().await }.boxed_local().fuse();
let coro = BuilderCoroutine(Rc::new(BuilderCoroutineData { cmd_recv, work: Mutex::new(work) }));
let coro = BuilderCoroutine(Rc::new(Mutex::new(BuilderCoroutineData { cmd_recv, work })));
coro.run().await
}
@@ -84,13 +84,13 @@ static WEIRD_DROP_ERR: &str = "Coroutine dropped while we are being polled someh
pub struct ExecHandle<'a>(Sender<Command>, PhantomData<&'a ()>);
impl ExecHandle<'_> {
pub async fn exec<T: TryFromExpr>(&mut self, val: impl ToExpr) -> OrcRes<T> {
let (reply_snd, reply_recv) = bounded(1);
let (reply_snd, mut reply_recv) = channel(0);
self.0.send(Command::Execute(val.to_expr().await, reply_snd)).await.expect(WEIRD_DROP_ERR);
T::try_from_expr(reply_recv.recv().await.expect(WEIRD_DROP_ERR)).await
T::try_from_expr(reply_recv.next().await.expect(WEIRD_DROP_ERR)).await
}
pub async fn register(&mut self, val: impl ToExpr) -> Expr {
let (reply_snd, reply_recv) = bounded(1);
let (reply_snd, mut reply_recv) = channel(0);
self.0.send(Command::Register(val.to_expr().await, reply_snd)).await.expect(WEIRD_DROP_ERR);
reply_recv.recv().await.expect(WEIRD_DROP_ERR)
reply_recv.next().await.expect(WEIRD_DROP_ERR)
}
}

View File

@@ -5,11 +5,10 @@ use std::num::NonZero;
use std::pin::Pin;
use std::rc::Rc;
use async_std::channel::{self, Receiver, Sender};
use async_std::stream;
use async_std::sync::Mutex;
use futures::channel::mpsc::{Receiver, Sender, channel};
use futures::future::{LocalBoxFuture, join_all};
use futures::{FutureExt, StreamExt, stream_select};
use futures::lock::Mutex;
use futures::{FutureExt, SinkExt, StreamExt, stream, stream_select};
use hashbrown::HashMap;
use itertools::Itertools;
use orchid_api::{ExtMsgSet, IntReq};
@@ -85,16 +84,16 @@ pub async fn with_atom_record<'a, F: Future<Output = SysCtx>, T>(
pub struct ExtensionOwner {
_interner_cell: Rc<RefCell<Option<Interner>>>,
_systems_lock: Rc<Mutex<HashMap<api::SysId, SystemRecord>>>,
out_recv: Receiver<Vec<u8>>,
out_recv: Mutex<Receiver<Vec<u8>>>,
out_send: Sender<Vec<u8>>,
}
impl ExtPort for ExtensionOwner {
fn send<'a>(&'a self, msg: &'a [u8]) -> LocalBoxFuture<'a, ()> {
Box::pin(async { self.out_send.send(msg.to_vec()).boxed_local().await.unwrap() })
Box::pin(async { self.out_send.clone().send(msg.to_vec()).boxed_local().await.unwrap() })
}
fn recv(&self) -> LocalBoxFuture<'_, Option<Vec<u8>>> {
Box::pin(async { (self.out_recv.recv().await).ok() })
Box::pin(async { self.out_recv.lock().await.next().await })
}
}
@@ -110,9 +109,9 @@ pub fn extension_init(
.collect_vec();
let systems_lock = Rc::new(Mutex::new(HashMap::<api::SysId, SystemRecord>::new()));
let ext_header = api::ExtensionHeader { name: data.name.to_string(), systems: decls.clone() };
let (out_send, in_recv) = channel::bounded::<Vec<u8>>(1);
let (in_send, out_recv) = channel::bounded::<Vec<u8>>(1);
let (exit_send, exit_recv) = channel::bounded(1);
let (out_send, in_recv) = channel::<Vec<u8>>(1);
let (in_send, out_recv) = channel::<Vec<u8>>(1);
let (exit_send, exit_recv) = channel(1);
let logger = Logger::new(log_strategy);
let msg_logger = Logger::new(msg_logs);
let interner_cell = Rc::new(RefCell::new(None::<Interner>));
@@ -136,22 +135,30 @@ pub fn extension_init(
};
let rn = ReqNot::<api::ExtMsgSet>::new(
msg_logger.clone(),
move |a, _| clone!(in_send; Box::pin(async move { in_send.send(a.to_vec()).await.unwrap() })),
clone!(systems_weak, exit_send, get_ctx; move |n, _| {
clone!(systems_weak, exit_send, get_ctx; async move {
match n {
api::HostExtNotif::Exit => exit_send.send(()).await.unwrap(),
api::HostExtNotif::SystemDrop(api::SystemDrop(sys_id)) =>
if let Some(rc) = systems_weak.upgrade() {
mem::drop(rc.lock().await.remove(&sys_id))
move |a, _| {
clone!(in_send mut);
Box::pin(async move { in_send.send(a.to_vec()).await.unwrap() })
},
{
clone!(systems_weak, exit_send, get_ctx);
move |n, _| {
clone!(systems_weak, exit_send mut, get_ctx);
async move {
match n {
api::HostExtNotif::Exit => exit_send.send(()).await.unwrap(),
api::HostExtNotif::SystemDrop(api::SystemDrop(sys_id)) =>
if let Some(rc) = systems_weak.upgrade() {
mem::drop(rc.lock().await.remove(&sys_id))
},
api::HostExtNotif::AtomDrop(api::AtomDrop(sys_id, atom)) => {
let ctx = get_ctx(sys_id).await;
take_atom(atom, &ctx).await.dyn_free(ctx.clone()).await
},
api::HostExtNotif::AtomDrop(api::AtomDrop(sys_id, atom)) => {
let ctx = get_ctx(sys_id).await;
take_atom(atom, &ctx).await.dyn_free(ctx.clone()).await
}
}
}.boxed_local())
}),
.boxed_local()
}
},
{
clone!(logger, get_ctx, init_ctx, systems_weak, interner_weak, decls, msg_logger);
move |hand, req| {
@@ -174,7 +181,7 @@ pub fn extension_init(
});
let lazy_mems = Mutex::new(HashMap::new());
let ctx = init_ctx(new_sys.id, cted.clone(), hand.reqnot()).await;
let const_root = stream::from_iter(cted.inst().dyn_env())
let const_root = stream::iter(cted.inst().dyn_env())
.then(|mem| {
let (req, lazy_mems) = (&hand, &lazy_mems);
clone!(i, ctx; async move {
@@ -375,7 +382,7 @@ pub fn extension_init(
ExtInit {
header: ext_header,
port: Box::new(ExtensionOwner {
out_recv,
out_recv: Mutex::new(out_recv),
out_send,
_interner_cell: interner_cell,
_systems_lock: systems_lock,

View File

@@ -10,10 +10,9 @@ use std::future::Future;
use std::pin::Pin;
use std::rc::Rc;
use async_std::io::Write;
use async_std::sync::Mutex;
use futures::FutureExt;
use futures::future::LocalBoxFuture;
use futures::lock::Mutex;
use futures::{AsyncWrite, FutureExt};
use itertools::Itertools;
use never::Never;
use orchid_api_traits::Encode;
@@ -111,7 +110,7 @@ impl OwnedAtom for Fun {
}
}
async fn call(self, arg: Expr) -> GExpr { self.call_ref(arg).await }
async fn serialize(&self, _: SysCtx, write: Pin<&mut (impl Write + ?Sized)>) -> Self::Refs {
async fn serialize(&self, _: SysCtx, write: Pin<&mut (impl AsyncWrite + ?Sized)>) -> Self::Refs {
self.path.to_api().encode(write).await;
self.args.clone()
}

View File

@@ -10,7 +10,7 @@ pub mod expr;
pub mod func_atom;
pub mod gen_expr;
pub mod lexer;
pub mod msg;
// pub mod msg;
pub mod other_system;
pub mod parser;
pub mod reflection;

View File

@@ -1,12 +1,9 @@
use std::pin::pin;
use async_once_cell::OnceCell;
use async_std::io::{self, Stdout};
use async_std::sync::Mutex;
use futures::lock::Mutex;
use orchid_base::msg::{recv_msg, send_msg};
static STDOUT: OnceCell<Mutex<Stdout>> = OnceCell::new();
pub async fn send_parent_msg(msg: &[u8]) -> io::Result<()> {
let stdout_lk = STDOUT.get_or_init(async { Mutex::new(io::stdout()) }).await;
let mut stdout_g = stdout_lk.lock().await;

View File

@@ -1,8 +1,8 @@
use std::cell::OnceCell;
use std::rc::Rc;
use async_std::sync::Mutex;
use futures::FutureExt;
use futures::lock::Mutex;
use memo_map::MemoMap;
use orchid_base::interner::Tok;
use orchid_base::name::{NameLike, VPath};

View File

@@ -62,7 +62,7 @@ pub trait SystemCtor: Send + Sync + 'static {
type Instance: System;
const NAME: &'static str;
const VERSION: f64;
fn inst() -> Option<Self::Instance>;
fn inst(deps: <Self::Deps as DepDef>::Sat) -> Self::Instance;
}
pub trait DynSystemCtor: Send + Sync + 'static {
@@ -81,8 +81,8 @@ impl<T: SystemCtor> DynSystemCtor for T {
}
fn new_system(&self, api::NewSystem { system: _, id: _, depends }: &api::NewSystem) -> CtedObj {
let mut ids = depends.iter().copied();
let inst = Arc::new(T::inst().expect("Constructor did not create system"));
let deps = T::Deps::create(&mut || ids.next().unwrap());
let inst = Arc::new(T::inst(deps.clone()));
Arc::new(Cted::<T> { deps, inst })
}
}

View File

@@ -4,23 +4,27 @@ use crate::entrypoint::ExtensionData;
pub async fn tokio_main(data: ExtensionData) {
use std::io::Write;
use std::mem;
use std::pin::Pin;
use std::pin::{Pin, pin};
use std::rc::Rc;
use async_std::io;
use async_once_cell::OnceCell;
use futures::StreamExt;
use futures::future::LocalBoxFuture;
use futures::lock::Mutex;
use futures::stream::FuturesUnordered;
use orchid_api_traits::{Decode, Encode};
use orchid_base::msg::{recv_msg, send_msg};
use tokio::io;
use tokio::io::Stdout;
use tokio::task::{LocalSet, spawn_local};
use tokio_util::compat::{Compat, TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
use crate::api;
use crate::entrypoint::extension_init;
use crate::msg::{recv_parent_msg, send_parent_msg};
let local_set = LocalSet::new();
local_set.spawn_local(async {
let host_header = api::HostHeader::decode(Pin::new(&mut async_std::io::stdin())).await;
let host_header = api::HostHeader::decode(Pin::new(&mut tokio::io::stdin().compat())).await;
let init =
Rc::new(extension_init(data, host_header, Rc::new(|fut| mem::drop(spawn_local(fut)))));
let mut buf = Vec::new();
@@ -32,7 +36,7 @@ pub async fn tokio_main(data: ExtensionData) {
let mut io = FuturesUnordered::<LocalBoxFuture<()>>::new();
io.push(Box::pin(async {
loop {
match recv_parent_msg().await {
match recv_msg(pin!(io::stdin().compat())).await {
Ok(msg) => init.send(&msg[..]).await,
Err(e) if e.kind() == io::ErrorKind::BrokenPipe => break,
Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => break,
@@ -42,7 +46,10 @@ pub async fn tokio_main(data: ExtensionData) {
}));
io.push(Box::pin(async {
while let Some(msg) = init.recv().await {
send_parent_msg(&msg[..]).await.unwrap();
static STDOUT: OnceCell<Mutex<Compat<Stdout>>> = OnceCell::new();
let stdout_lk = STDOUT.get_or_init(async { Mutex::new(io::stdout().compat_write()) }).await;
let mut stdout_g = stdout_lk.lock().await;
send_msg(pin!(&mut *stdout_g), &msg[..]).await.expect("Parent pipe broken");
}
}));
io.next().await;