#![feature(impl_trait_in_assoc_type)] use std::future::Future; use generic_session_types::*; // #[derive(Choose)] enum Proto1 { P1(Send), // 1 P2(Recv), // 2 P3(Close), // 3 } /* begin proc macro gen */ struct Proto1Dual { p1: as HasDual>::Dual, p2: as HasDual>::Dual, p3: ::Dual, } async fn p1(chan: Chan) -> Result, E, C>, Error> where ::R: generic_session_types::Repr, { let mut c = chan.into_raw(); c.send(>::from(1)).await?; Ok(Chan::from_raw(c)) } impl HasDual for Proto1 { type Dual = Proto1Dual; } impl HasDual for Proto1Dual { type Dual = Proto1; } trait Proto1ChanExt { type C: RawChan; type P1Future: Future, E, Self::C>, Error>> + 'static where Self: 'static; fn p1(self) -> Self::P1Future; } impl Proto1ChanExt for Chan where C::R: Repr, { type C = C; type P1Future = impl Future, E, Self::C>, Error>> + 'static where Self:'static; fn p1(self) -> Self::P1Future { let mut c = self.into_raw(); async move { c.send(>::from(1)).await?; Ok(Chan::from_raw(c)) } } } pub enum Proto1DualOffer { P1(Chan< as HasDual>::Dual, E, C>), P2(Chan< as HasDual>::Dual, E, C>), P3(Chan<::Dual, E, C>), } // trait Proto1DualChanExt { // type C: RawChan; // type OfferFuture: Future, Error>> + 'static // where // Self: 'static; // fn offer(self) -> Self::OfferFuture; // } impl OfferExt for Chan where C::R: Repr, { type C = C; type OfferChan = Proto1DualOffer; type OfferFuture = impl Future> + 'static where Self:'static; fn offer(self) -> Self::OfferFuture { let mut c = self.into_raw(); async move { let r = c.recv().await.map_err(|_| Error::RecvErr)?; let t: u8 = Repr::try_into(r).map_err(|_| Error::ConvertErr)?; match t { 1 => Ok(Proto1DualOffer::P1(Chan::from_raw(c))), 2 => Ok(Proto1DualOffer::P2(Chan::from_raw(c))), 3 => Ok(Proto1DualOffer::P3(Chan::from_raw(c))), _ => Err(Error::ConvertErr), } } } } /* end proc macro gen */ async fn server(c: Chan + 'static>) -> Result<(), Error> { let c = c.p1().await?; let c = c.send(1).await?; c.close().await?; Ok(()) } #[tokio::test] async fn t1() {}