#![feature(impl_trait_in_assoc_type)]
use std::future::Future;
use generic_session_types::*;
enum Proto1 {
P1(Send<u32, Close>), P2(Recv<String, Close>), P3(Close), }
struct Proto1Dual {
p1: <Send<u32, Close> as HasDual>::Dual,
p2: <Recv<String, Close> as HasDual>::Dual,
p3: <Close as HasDual>::Dual,
}
async fn p1<E, C: RawChan>(chan: Chan<Proto1, E, C>) -> Result<Chan<Send<u32, Close>, E, C>, Error>
where
<C as generic_session_types::RawChan>::R: generic_session_types::Repr<u8>,
{
let mut c = chan.into_raw();
c.send(<C::R as Repr<u8>>::from(1)).await?;
Ok(Chan::from_raw(c))
}
impl HasDual for Proto1 {
type Dual = Proto1Dual;
}
impl HasDual for Proto1Dual {
type Dual = Proto1;
}
trait Proto1ChanExt<E> {
type C: RawChan;
type P1Future: Future<Output = Result<Chan<Send<u32, Close>, E, Self::C>, Error>> + 'static
where
Self: 'static;
fn p1(self) -> Self::P1Future;
}
impl<C: RawChan, E> Proto1ChanExt<E> for Chan<Proto1, E, C>
where
C::R: Repr<u8>,
{
type C = C;
type P1Future = impl Future<Output = Result<Chan<Send<u32, Close>, E, Self::C>, Error>> + 'static where Self:'static;
fn p1(self) -> Self::P1Future {
let mut c = self.into_raw();
async move {
c.send(<C::R as Repr<u8>>::from(1)).await?;
Ok(Chan::from_raw(c))
}
}
}
pub enum Proto1DualOffer<E, C: RawChan> {
P1(Chan<<Send<u32, Close> as HasDual>::Dual, E, C>),
P2(Chan<<Recv<String, Close> as HasDual>::Dual, E, C>),
P3(Chan<<Close as HasDual>::Dual, E, C>),
}
impl<E, C: RawChan> OfferExt<Proto1Dual, E> for Chan<Proto1Dual, E, C>
where
C::R: Repr<u8>,
{
type C = C;
type OfferChan = Proto1DualOffer<E, Self::C>;
type OfferFuture = impl Future<Output = Result<Self::OfferChan, Error>> + '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),
}
}
}
}
async fn server(c: Chan<Proto1, (), impl RawChan<R = BoxAnyRepr> + 'static>) -> Result<(), Error> {
let c = c.p1().await?;
let c = c.send(1).await?;
c.close().await?;
Ok(())
}
#[tokio::test]
async fn t1() {}