Pending a correct test of request cancellation
This commit is contained in:
@@ -184,27 +184,15 @@ pub trait AtomMethod: Coding + InHierarchy {
|
||||
/// A handler for an [AtomMethod] on an [Atomic]. The [AtomMethod] must also be
|
||||
/// registered in [Atomic::reg_methods]
|
||||
pub trait Supports<M: AtomMethod>: Atomic {
|
||||
fn handle<'a>(
|
||||
&self,
|
||||
hand: Box<dyn ReqHandle<'a> + '_>,
|
||||
req: M,
|
||||
) -> impl Future<Output = io::Result<Receipt<'a>>>;
|
||||
fn handle(&self, hand: Box<dyn ReqHandle>, req: M) -> impl Future<Output = io::Result<Receipt>>;
|
||||
}
|
||||
|
||||
trait HandleAtomMethod<A> {
|
||||
fn handle<'a, 'b: 'a>(
|
||||
&'a self,
|
||||
atom: &'a A,
|
||||
reader: Box<dyn ReqReader<'b> + 'a>,
|
||||
) -> LocalBoxFuture<'a, ()>;
|
||||
fn handle<'a>(&'a self, atom: &'a A, reader: Box<dyn ReqReader>) -> LocalBoxFuture<'a, ()>;
|
||||
}
|
||||
struct AtomMethodHandler<M, A>(PhantomData<M>, PhantomData<A>);
|
||||
impl<M: AtomMethod, A: Supports<M>> HandleAtomMethod<A> for AtomMethodHandler<M, A> {
|
||||
fn handle<'a, 'b: 'a>(
|
||||
&'a self,
|
||||
atom: &'a A,
|
||||
mut reader: Box<dyn ReqReader<'b> + 'a>,
|
||||
) -> LocalBoxFuture<'a, ()> {
|
||||
fn handle<'a>(&'a self, atom: &'a A, mut reader: Box<dyn ReqReader>) -> LocalBoxFuture<'a, ()> {
|
||||
Box::pin(async {
|
||||
let req = reader.read_req::<M>().await.unwrap();
|
||||
let _ = Supports::<M>::handle(atom, reader.finish().await, req).await.unwrap();
|
||||
@@ -244,12 +232,7 @@ pub(crate) struct MethodSet<A: Atomic> {
|
||||
handlers: HashMap<Sym, Rc<dyn HandleAtomMethod<A>>>,
|
||||
}
|
||||
impl<A: Atomic> MethodSet<A> {
|
||||
pub(crate) async fn dispatch<'a>(
|
||||
&self,
|
||||
atom: &'_ A,
|
||||
key: Sym,
|
||||
req: Box<dyn ReqReader<'a> + 'a>,
|
||||
) -> bool {
|
||||
pub(crate) async fn dispatch(&self, atom: &A, key: Sym, req: Box<dyn ReqReader>) -> bool {
|
||||
match self.handlers.get(&key) {
|
||||
None => false,
|
||||
Some(handler) => {
|
||||
@@ -341,7 +324,7 @@ pub trait AtomOps: 'static {
|
||||
&'a self,
|
||||
ctx: AtomCtx<'a>,
|
||||
key: Sym,
|
||||
req: Box<dyn ReqReader<'a> + 'a>,
|
||||
req: Box<dyn ReqReader>,
|
||||
) -> LocalBoxFuture<'a, bool>;
|
||||
fn serialize<'a, 'b: 'a>(
|
||||
&'a self,
|
||||
|
||||
@@ -119,7 +119,7 @@ impl<A: OwnedAtom> AtomOps for OwnedAtomOps<A> {
|
||||
&'a self,
|
||||
AtomCtx(_, id): AtomCtx<'a>,
|
||||
key: Sym,
|
||||
req: Box<dyn orchid_base::ReqReader<'a> + 'a>,
|
||||
req: Box<dyn orchid_base::ReqReader>,
|
||||
) -> LocalBoxFuture<'a, bool> {
|
||||
Box::pin(async move {
|
||||
let a = AtomReadGuard::new(id.unwrap()).await;
|
||||
|
||||
@@ -53,7 +53,7 @@ impl<T: ThinAtom> AtomOps for ThinAtomOps<T> {
|
||||
&'a self,
|
||||
AtomCtx(buf, ..): AtomCtx<'a>,
|
||||
key: Sym,
|
||||
req: Box<dyn orchid_base::ReqReader<'a> + 'a>,
|
||||
req: Box<dyn orchid_base::ReqReader>,
|
||||
) -> LocalBoxFuture<'a, bool> {
|
||||
Box::pin(async move {
|
||||
let ms = self.ms.get_or_init(self.msbuild.pack()).await;
|
||||
|
||||
@@ -6,7 +6,7 @@ use never::Never;
|
||||
use orchid_base::{Receipt, ReqHandle, ReqHandleExt};
|
||||
|
||||
use crate::gen_expr::{GExpr, new_atom, serialize};
|
||||
use crate::std_reqs::RunCommand;
|
||||
use crate::std_reqs::StartCommand;
|
||||
use crate::{Atomic, MethodSetBuilder, OwnedAtom, OwnedVariant, Supports, ToExpr};
|
||||
|
||||
pub trait AsyncFnDyn {
|
||||
@@ -21,18 +21,14 @@ pub struct CmdAtom(Rc<dyn AsyncFnDyn>);
|
||||
impl Atomic for CmdAtom {
|
||||
type Data = ();
|
||||
type Variant = OwnedVariant;
|
||||
fn reg_methods() -> MethodSetBuilder<Self> { MethodSetBuilder::new().handle::<RunCommand>() }
|
||||
fn reg_methods() -> MethodSetBuilder<Self> { MethodSetBuilder::new().handle::<StartCommand>() }
|
||||
}
|
||||
impl Supports<RunCommand> for CmdAtom {
|
||||
async fn handle<'a>(
|
||||
&self,
|
||||
hand: Box<dyn ReqHandle<'a> + '_>,
|
||||
req: RunCommand,
|
||||
) -> std::io::Result<Receipt<'a>> {
|
||||
impl Supports<StartCommand> for CmdAtom {
|
||||
async fn handle(&self, hand: Box<dyn ReqHandle>, req: StartCommand) -> std::io::Result<Receipt> {
|
||||
let reply = self.0.call().await;
|
||||
match reply {
|
||||
None => hand.reply(&req, &None).await,
|
||||
Some(next) => hand.reply(&req, &Some(serialize(next).await)).await,
|
||||
None => hand.reply(&req, None).await,
|
||||
Some(next) => hand.reply(&req, Some(serialize(next).await)).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
|
||||
use futures::future::{LocalBoxFuture, join_all};
|
||||
use futures::{AsyncWriteExt, StreamExt, stream};
|
||||
use futures::future::{LocalBoxFuture, join_all, join3};
|
||||
use futures::{AsyncReadExt, AsyncWriteExt, StreamExt, stream};
|
||||
use hashbrown::HashMap;
|
||||
use itertools::Itertools;
|
||||
use orchid_api_traits::{Decode, Encode, Request, UnderRoot, enc_vec};
|
||||
use orchid_async_utils::{Handle, to_task};
|
||||
use orchid_async_utils::{Handle, JoinError, to_task};
|
||||
use orchid_base::{
|
||||
Client, ClientExt, CommCtx, Comment, MsgReader, MsgReaderExt, ReqHandleExt, ReqReaderExt,
|
||||
Snippet, Sym, TokenVariant, Witness, char_filter_match, char_filter_union, es, io_comm, is, log,
|
||||
@@ -21,6 +21,7 @@ use orchid_base::{
|
||||
};
|
||||
use substack::Substack;
|
||||
use task_local::task_local;
|
||||
use unsync_pipe::pipe;
|
||||
|
||||
use crate::gen_expr::serialize;
|
||||
use crate::interner::new_interner;
|
||||
@@ -74,7 +75,7 @@ pub async fn request<T: Request + UnderRoot<Root = api::ExtHostReq>>(t: T) -> T:
|
||||
}
|
||||
|
||||
/// Send a notification through the global client's [ClientExt::notify]
|
||||
pub async fn notify<T: UnderRoot<Root = api::ExtHostNotif>>(t: T) {
|
||||
pub async fn notify<T: UnderRoot<Root = api::ExtHostNotif> + 'static>(t: T) {
|
||||
get_client().notify(t).await.unwrap()
|
||||
}
|
||||
|
||||
@@ -106,7 +107,7 @@ impl<F: AsyncFnOnce(LocalBoxFuture<'_, ()>) + 'static> ContextModifier for F {
|
||||
|
||||
pub(crate) trait DynTaskHandle: 'static {
|
||||
fn abort(self: Box<Self>);
|
||||
fn join(self: Box<Self>) -> LocalBoxFuture<'static, Box<dyn Any>>;
|
||||
fn join(self: Box<Self>) -> LocalBoxFuture<'static, Result<Box<dyn Any>, JoinError>>;
|
||||
}
|
||||
|
||||
task_local! {
|
||||
@@ -124,7 +125,7 @@ impl<T: 'static> TaskHandle<T> {
|
||||
/// Stop working on the task and return the nested future. The distinction
|
||||
/// between this and waiting until the task is complete without reparenting it
|
||||
/// is significant for the purpose of [task_local] context
|
||||
pub async fn join(self) -> T { *self.0.join().await.downcast().unwrap() }
|
||||
pub async fn join(self) -> Result<T, JoinError> { Ok(*self.0.join().await?.downcast().unwrap()) }
|
||||
}
|
||||
|
||||
/// Spawn a future that is not associated with a pending request or a past
|
||||
@@ -138,7 +139,9 @@ pub fn spawn<F: Future<Output: 'static> + 'static>(delay: Duration, f: F) -> Tas
|
||||
|
||||
impl DynTaskHandle for Handle<Box<dyn Any>> {
|
||||
fn abort(self: Box<Self>) { Self::abort(&self); }
|
||||
fn join(self: Box<Self>) -> LocalBoxFuture<'static, Box<dyn Any>> { Box::pin(Self::join(*self)) }
|
||||
fn join(self: Box<Self>) -> LocalBoxFuture<'static, Result<Box<dyn Any>, JoinError>> {
|
||||
Box::pin(Self::join(*self))
|
||||
}
|
||||
}
|
||||
|
||||
/// A new Orchid extension as specified in loaders. An extension is a unit of
|
||||
@@ -213,15 +216,15 @@ impl ExtensionBuilder {
|
||||
match req {
|
||||
api::HostExtReq::SystemDrop(sys_drop) => {
|
||||
SYSTEM_TABLE.with(|l| l.borrow_mut().remove(&sys_drop.0));
|
||||
handle.reply(&sys_drop, &()).await
|
||||
handle.reply(&sys_drop, ()).await
|
||||
},
|
||||
api::HostExtReq::AtomDrop(atom_drop @ api::AtomDrop(sys_id, atom)) =>
|
||||
with_sys_record(sys_id, async {
|
||||
take_atom(atom).await.dyn_free().await;
|
||||
handle.reply(&atom_drop, &()).await
|
||||
handle.reply(&atom_drop, ()).await
|
||||
})
|
||||
.await,
|
||||
api::HostExtReq::Ping(ping @ api::Ping) => handle.reply(&ping, &()).await,
|
||||
api::HostExtReq::Ping(ping @ api::Ping) => handle.reply(&ping, ()).await,
|
||||
api::HostExtReq::Sweep(api::Sweep) => todo!(),
|
||||
api::HostExtReq::SysReq(api::SysReq::NewSystem(new_sys)) => {
|
||||
let (ctor_idx, _) = (decls.iter().enumerate().find(|(_, s)| s.id == new_sys.system))
|
||||
@@ -257,7 +260,7 @@ impl ExtensionBuilder {
|
||||
.await;
|
||||
let response =
|
||||
api::NewSystemResponse { lex_filter, const_root, line_types, prelude };
|
||||
handle.reply(&new_sys, &response).await
|
||||
handle.reply(&new_sys, response).await
|
||||
})
|
||||
.await
|
||||
},
|
||||
@@ -266,17 +269,23 @@ impl ExtensionBuilder {
|
||||
let (path, tree) = get_lazy(tree_id).await;
|
||||
let mut tia_ctx =
|
||||
TreeIntoApiCtxImpl { path: Substack::Bottom, basepath: &path[..] };
|
||||
handle.reply(&get_tree, &tree.into_api(&mut tia_ctx).await).await
|
||||
handle.reply(&get_tree, tree.into_api(&mut tia_ctx).await).await
|
||||
})
|
||||
.await,
|
||||
api::HostExtReq::SysReq(api::SysReq::SysFwded(fwd)) => {
|
||||
let fwd_tok = Witness::of(&fwd);
|
||||
let api::SysFwded(sys_id, payload) = fwd;
|
||||
with_sys_record(sys_id, async {
|
||||
let (mut req_in, req) = pipe(1024);
|
||||
let (rep, mut rep_out) = pipe(1024);
|
||||
let mut reply = Vec::new();
|
||||
let req = TrivialReqCycle { req: &payload, rep: &mut reply };
|
||||
let _ = dyn_cted().inst().dyn_request(Box::new(req)).await;
|
||||
handle.reply(fwd_tok, &reply).await
|
||||
let (..) = join3(
|
||||
async { req_in.write_all(&payload).await.expect("Ingress failed") },
|
||||
async { rep_out.read_to_end(&mut reply).await.expect("Egress failed") },
|
||||
dyn_cted().inst().dyn_request(Box::new(TrivialReqCycle { req, rep })),
|
||||
)
|
||||
.await;
|
||||
handle.reply(fwd_tok, reply).await
|
||||
})
|
||||
.await
|
||||
},
|
||||
@@ -298,7 +307,7 @@ impl ExtensionBuilder {
|
||||
Err(e) => {
|
||||
let eopt = e.keep_only(|e| *e != ekey_cascade).map(|e| Err(e.to_api()));
|
||||
expr_store.dispose().await;
|
||||
return handle.reply(&lex, &eopt).await;
|
||||
return handle.reply(&lex, eopt).await;
|
||||
},
|
||||
Ok((s, expr)) => {
|
||||
let expr = join_all(
|
||||
@@ -308,13 +317,13 @@ impl ExtensionBuilder {
|
||||
.await;
|
||||
let pos = (text.len() - s.len()) as u32;
|
||||
expr_store.dispose().await;
|
||||
return handle.reply(&lex, &Some(Ok(api::LexedExpr { pos, expr }))).await;
|
||||
return handle.reply(&lex, Some(Ok(api::LexedExpr { pos, expr }))).await;
|
||||
},
|
||||
}
|
||||
}
|
||||
writeln!(log("warn"), "Got notified about n/a character '{trigger_char}'").await;
|
||||
expr_store.dispose().await;
|
||||
handle.reply(&lex, &None).await
|
||||
handle.reply(&lex, None).await
|
||||
})
|
||||
.await,
|
||||
api::HostExtReq::ParseLine(pline) => {
|
||||
@@ -338,14 +347,14 @@ impl ExtensionBuilder {
|
||||
};
|
||||
mem::drop(line);
|
||||
expr_store.dispose().await;
|
||||
handle.reply(req, &o_line).await
|
||||
handle.reply(req, o_line).await
|
||||
})
|
||||
.await
|
||||
},
|
||||
api::HostExtReq::FetchParsedConst(ref fpc @ api::FetchParsedConst(sys, id)) =>
|
||||
with_sys_record(sys, async {
|
||||
let cnst = get_const(id).await;
|
||||
handle.reply(fpc, &serialize(cnst).await).await
|
||||
handle.reply(fpc, serialize(cnst).await).await
|
||||
})
|
||||
.await,
|
||||
api::HostExtReq::AtomReq(atom_req) => {
|
||||
@@ -357,24 +366,30 @@ impl ExtensionBuilder {
|
||||
api::AtomReq::SerializeAtom(ser) => {
|
||||
let mut buf = enc_vec(&id);
|
||||
match nfo.serialize(actx, Pin::<&mut Vec<_>>::new(&mut buf)).await {
|
||||
None => handle.reply(ser, &None).await,
|
||||
None => handle.reply(ser, None).await,
|
||||
Some(refs) => {
|
||||
let refs =
|
||||
join_all(refs.into_iter().map(async |ex| ex.into_api(&mut ()).await))
|
||||
.await;
|
||||
handle.reply(ser, &Some((buf, refs))).await
|
||||
handle.reply(ser, Some((buf, refs))).await
|
||||
},
|
||||
}
|
||||
},
|
||||
api::AtomReq::AtomPrint(print @ api::AtomPrint(_)) =>
|
||||
handle.reply(print, &nfo.print(actx).await.to_api()).await,
|
||||
handle.reply(print, nfo.print(actx).await.to_api()).await,
|
||||
api::AtomReq::Fwded(fwded) => {
|
||||
let api::Fwded(_, key, payload) = &fwded;
|
||||
let (mut req_in, req) = pipe(1024);
|
||||
let (rep, mut rep_out) = pipe(1024);
|
||||
let mut reply = Vec::new();
|
||||
let key = Sym::from_api(*key).await;
|
||||
let req = TrivialReqCycle { req: payload, rep: &mut reply };
|
||||
let some = nfo.handle_req_ref(actx, key, Box::new(req)).await;
|
||||
handle.reply(fwded, &some.then_some(reply)).await
|
||||
let (.., some) = join3(
|
||||
async { req_in.write_all(payload).await.expect("Ingress failed") },
|
||||
async { rep_out.read_to_end(&mut reply).await.expect("Egress failed") },
|
||||
nfo.handle_req_ref(actx, key, Box::new(TrivialReqCycle { req, rep })),
|
||||
)
|
||||
.await;
|
||||
handle.reply(fwded, some.then_some(reply)).await
|
||||
},
|
||||
api::AtomReq::CallRef(call @ api::CallRef(_, arg)) => {
|
||||
let expr_store = BorrowedExprStore::new();
|
||||
@@ -383,7 +398,7 @@ impl ExtensionBuilder {
|
||||
let api_expr = serialize(ret).await;
|
||||
mem::drop(expr_handle);
|
||||
expr_store.dispose().await;
|
||||
handle.reply(call, &api_expr).await
|
||||
handle.reply(call, api_expr).await
|
||||
},
|
||||
api::AtomReq::FinalCall(call @ api::FinalCall(_, arg)) => {
|
||||
let expr_store = BorrowedExprStore::new();
|
||||
@@ -392,7 +407,7 @@ impl ExtensionBuilder {
|
||||
let api_expr = serialize(ret).await;
|
||||
mem::drop(expr_handle);
|
||||
expr_store.dispose().await;
|
||||
handle.reply(call, &api_expr).await
|
||||
handle.reply(call, api_expr).await
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -409,7 +424,7 @@ impl ExtensionBuilder {
|
||||
let id = AtomTypeId::decode_slice(read);
|
||||
let nfo = (dyn_cted().inst().card().ops_by_atid(id))
|
||||
.expect("Deserializing atom with invalid ID");
|
||||
handle.reply(&deser, &nfo.deserialize(read, &refs).await).await
|
||||
handle.reply(&deser, nfo.deserialize(read, &refs).await).await
|
||||
})
|
||||
.await
|
||||
},
|
||||
|
||||
@@ -16,11 +16,11 @@ impl Request for Spawn {
|
||||
|
||||
/// Execute the atom as a command.
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
|
||||
pub struct RunCommand;
|
||||
impl Request for RunCommand {
|
||||
pub struct StartCommand;
|
||||
impl Request for StartCommand {
|
||||
type Response = Option<api::Expression>;
|
||||
}
|
||||
impl AtomMethod for RunCommand {
|
||||
impl AtomMethod for StartCommand {
|
||||
const NAME: &str = "orchid::cmd::run";
|
||||
}
|
||||
|
||||
|
||||
@@ -40,23 +40,19 @@ impl OwnedAtom for WriterAtom {
|
||||
async fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(()) }
|
||||
}
|
||||
impl Supports<OutputReq> for WriterAtom {
|
||||
async fn handle<'a>(
|
||||
&self,
|
||||
hand: Box<dyn ReqHandle<'a> + '_>,
|
||||
req: OutputReq,
|
||||
) -> Result<Receipt<'a>> {
|
||||
async fn handle(&self, hand: Box<dyn ReqHandle>, req: OutputReq) -> Result<Receipt> {
|
||||
match req {
|
||||
OutputReq::WriteReq(ref wr @ WriteReq { ref data }) => {
|
||||
self.0.lock().await.buf.extend(data);
|
||||
hand.reply(wr, &Ok(())).await
|
||||
hand.reply(wr, Ok(())).await
|
||||
},
|
||||
OutputReq::FlushReq(ref fr @ FlushReq) => {
|
||||
let mut g = self.0.lock().await;
|
||||
let WriterState { buf, writer } = &mut *g;
|
||||
hand.reply(fr, &writer.write_all(&buf[..]).await.map_err(|e| e.into())).await
|
||||
hand.reply(fr, writer.write_all(&buf[..]).await.map_err(|e| e.into())).await
|
||||
},
|
||||
OutputReq::CloseReq(ref cr @ CloseReq) =>
|
||||
hand.reply(cr, &self.0.lock().await.writer.close().await.map_err(|e| e.into())).await,
|
||||
hand.reply(cr, self.0.lock().await.writer.close().await.map_err(|e| e.into())).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,11 +76,7 @@ impl OwnedAtom for ReaderAtom {
|
||||
async fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(()) }
|
||||
}
|
||||
impl Supports<ReadReq> for ReaderAtom {
|
||||
async fn handle<'a>(
|
||||
&self,
|
||||
hand: Box<dyn ReqHandle<'a> + '_>,
|
||||
req: ReadReq,
|
||||
) -> Result<Receipt<'a>> {
|
||||
async fn handle(&self, hand: Box<dyn ReqHandle>, req: ReadReq) -> Result<Receipt> {
|
||||
let mut buf = Vec::new();
|
||||
let mut reader = self.0.lock().await;
|
||||
let rep = match match req.limit {
|
||||
@@ -98,6 +90,6 @@ impl Supports<ReadReq> for ReaderAtom {
|
||||
Err(e) => Err(e.into()),
|
||||
Ok(()) => Ok(buf),
|
||||
};
|
||||
hand.reply(&req, &rep).await
|
||||
hand.reply(&req, rep).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ pub trait System: Debug + 'static {
|
||||
fn env(&self) -> impl Future<Output = Vec<GenMember>> { futures::future::ready(Vec::new()) }
|
||||
fn lexers(&self) -> Vec<LexerObj> { Vec::new() }
|
||||
fn parsers(&self) -> Vec<ParserObj> { Vec::new() }
|
||||
fn request<'a>(
|
||||
fn request(
|
||||
&self,
|
||||
hand: Box<dyn ReqHandle<'a> + 'a>,
|
||||
hand: Box<dyn ReqHandle>,
|
||||
req: ReqForSystem<Self>,
|
||||
) -> impl Future<Output = Receipt<'a>>;
|
||||
) -> impl Future<Output = Receipt>;
|
||||
}
|
||||
|
||||
pub trait DynSystem: Debug + 'static {
|
||||
@@ -32,10 +32,7 @@ pub trait DynSystem: Debug + 'static {
|
||||
fn dyn_env(&self) -> LocalBoxFuture<'_, Vec<GenMember>>;
|
||||
fn dyn_lexers(&self) -> Vec<LexerObj>;
|
||||
fn dyn_parsers(&self) -> Vec<ParserObj>;
|
||||
fn dyn_request<'a, 'b: 'a>(
|
||||
&'a self,
|
||||
hand: Box<dyn ReqReader<'b> + 'b>,
|
||||
) -> LocalBoxFuture<'a, Receipt<'b>>;
|
||||
fn dyn_request<'a, 'b: 'a>(&'a self, hand: Box<dyn ReqReader>) -> LocalBoxFuture<'a, Receipt>;
|
||||
fn card(&self) -> Box<dyn DynSystemCard>;
|
||||
}
|
||||
|
||||
@@ -46,8 +43,8 @@ impl<T: System> DynSystem for T {
|
||||
fn dyn_parsers(&self) -> Vec<ParserObj> { self.parsers() }
|
||||
fn dyn_request<'a, 'b: 'a>(
|
||||
&'a self,
|
||||
mut hand: Box<dyn ReqReader<'b> + 'b>,
|
||||
) -> LocalBoxFuture<'a, Receipt<'b>> {
|
||||
mut hand: Box<dyn ReqReader>,
|
||||
) -> LocalBoxFuture<'a, Receipt> {
|
||||
Box::pin(async move {
|
||||
let value = hand.read_req().await.unwrap();
|
||||
self.request(hand.finish().await, value).await
|
||||
|
||||
@@ -4,25 +4,26 @@ use std::pin::Pin;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::{AsyncRead, AsyncWrite};
|
||||
use orchid_base::{Receipt, RepWriter, ReqHandle, ReqReader};
|
||||
use unsync_pipe::{Reader, Writer};
|
||||
|
||||
pub struct TrivialReqCycle<'a> {
|
||||
pub req: &'a [u8],
|
||||
pub rep: &'a mut Vec<u8>,
|
||||
pub struct TrivialReqCycle {
|
||||
pub req: Reader,
|
||||
pub rep: Writer,
|
||||
}
|
||||
impl<'a> ReqReader<'a> for TrivialReqCycle<'a> {
|
||||
impl ReqReader for TrivialReqCycle {
|
||||
fn reader(&mut self) -> Pin<&mut dyn AsyncRead> { Pin::new(&mut self.req) as Pin<&mut _> }
|
||||
fn finish(self: Box<Self>) -> LocalBoxFuture<'a, Box<dyn ReqHandle<'a> + 'a>> {
|
||||
fn finish(self: Box<Self>) -> LocalBoxFuture<'static, Box<dyn ReqHandle>> {
|
||||
Box::pin(async { self as Box<_> })
|
||||
}
|
||||
}
|
||||
impl<'a> ReqHandle<'a> for TrivialReqCycle<'a> {
|
||||
fn start_reply(self: Box<Self>) -> LocalBoxFuture<'a, io::Result<Box<dyn RepWriter<'a> + 'a>>> {
|
||||
impl ReqHandle for TrivialReqCycle {
|
||||
fn start_reply(self: Box<Self>) -> LocalBoxFuture<'static, io::Result<Box<dyn RepWriter>>> {
|
||||
Box::pin(async { Ok(self as Box<_>) })
|
||||
}
|
||||
}
|
||||
impl<'a> RepWriter<'a> for TrivialReqCycle<'a> {
|
||||
impl RepWriter for TrivialReqCycle {
|
||||
fn writer(&mut self) -> Pin<&mut dyn AsyncWrite> { Pin::new(&mut self.rep) as Pin<&mut _> }
|
||||
fn finish(self: Box<Self>) -> LocalBoxFuture<'a, io::Result<Receipt<'a>>> {
|
||||
fn finish(self: Box<Self>) -> LocalBoxFuture<'static, io::Result<Receipt>> {
|
||||
Box::pin(async { Ok(Receipt::_new()) })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user