ferrite_session/internal/session/
include.rs1use std::collections::LinkedList;
2
3use crate::internal::{
4 base::{
5 AppendContext,
6 Context,
7 ContextLens,
8 Empty,
9 PartialSession,
10 Protocol,
11 Session,
12 },
13 protocol::End,
14 session::{
15 context::append_emtpy_slot,
16 cut::{
17 AllRight,
18 Cut,
19 },
20 end::{
21 terminate,
22 wait,
23 },
24 },
25};
26
27pub fn include_session<C1, C2, N, A, B>(
28 session: Session<A>,
29 cont: impl FnOnce(N) -> PartialSession<C2, B>,
30) -> PartialSession<C1, B>
31where
32 A: Protocol,
33 B: Protocol,
34 C1: Context<Length = N>,
35 C2: Context,
36 C1: AppendContext<(A, ()), Appended = C2>,
37{
38 AllRight::cut(session, cont)
39}
40
41pub fn wait_session<I, P>(
42 session1: Session<End>,
43 cont: PartialSession<I, P>,
44) -> PartialSession<I, P>
45where
46 P: Protocol,
47 I: Context,
48 I: AppendContext<(End, ())>,
49 I: AppendContext<(Empty, ())>,
50 I::Length: ContextLens<
51 <I as AppendContext<(End, ())>>::Appended,
52 End,
53 Empty,
54 Target = <I as AppendContext<(Empty, ())>>::Appended,
55 >,
56{
57 include_session(session1, move |chan| wait(chan, append_emtpy_slot(cont)))
58}
59
60pub fn wait_sessions<I, P>(
61 sessions: Vec<Session<End>>,
62 cont: PartialSession<I, P>,
63) -> PartialSession<I, P>
64where
65 P: Protocol,
66 I: AppendContext<(End, ())>,
67 I: AppendContext<(Empty, ())>,
68 I::Length: ContextLens<
69 <I as AppendContext<(End, ())>>::Appended,
70 End,
71 Empty,
72 Target = <I as AppendContext<(Empty, ())>>::Appended,
73 >,
74{
75 wait_session(join_sessions(sessions), cont)
76}
77
78pub fn join_sessions(sessions: Vec<Session<End>>) -> Session<End>
79{
80 do_join_sessions(sessions.into_iter().collect())
81}
82
83fn do_join_sessions(mut sessions: LinkedList<Session<End>>) -> Session<End>
84{
85 match sessions.pop_front() {
86 Some(session) => include_session(session, move |c1| {
87 include_session(do_join_sessions(sessions), move |c2| {
88 wait(c1, wait(c2, terminate()))
89 })
90 }),
91 None => terminate(),
92 }
93}