-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcustom_choice.rs
106 lines (92 loc) · 2.9 KB
/
custom_choice.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#![feature(impl_trait_in_assoc_type)]
use std::future::Future;
use generic_session_types::*;
// #[derive(Choose)]
enum Proto1 {
P1(Send<u32, Close>), // 1
P2(Recv<String, Close>), // 2
P3(Close), // 3
}
/* begin proc macro gen */
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>),
}
// trait Proto1DualChanExt<E> {
// type C: RawChan;
// type OfferFuture: Future<Output = Result<Proto1DualOffer<E, Self::C>, Error>> + 'static
// where
// Self: 'static;
// fn offer(self) -> Self::OfferFuture;
// }
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),
}
}
}
}
/* end proc macro gen */
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() {}