pub struct Junction { /* private fields */ }Expand description
Struct managing the creation of new channels and Join Patterns.
This struct is used to group channels, such as SendChannel, which can
be used in conjunction to create new Join Patterns. As such, it offers
methods to create new channels which are then directly linked to this
Junction. It also offers methods to start off the creation of new
Join Patterns that rely on the channels created by this struct and can,
in fact, only consist of channels associated with this struct.
Implementations§
Source§impl Junction
impl Junction
Sourcepub fn new() -> Junction
pub fn new() -> Junction
Create a new Junction and start control thread in background.
Create a new Junction and spawn a control thread in the background
that will handle all incoming Packets for this Junction. A
JoinHandle to this control thread is stored alongside the Junction.
Examples found in repository?
4fn main() {
5 // Create a new Junction.
6 let j = Junction::new();
7
8 // Create new channels on the Junction j.
9 let name = j.send_channel::<String>();
10 let value = j.send_channel::<i32>();
11
12 // Declare a new Join Pattern on the Junction using the channels above.
13 j.when(&name).and(&value).then_do(|n, v| { println!("{} {}", n, v); });
14
15 // Send all the required messages for the Join Pattern above to fire.
16 value.send(1729).unwrap();
17 name.send(String::from("Taxi")).unwrap();
18}More examples
3fn main() {
4 /* Start of the Join Pattern setup. */
5
6 // Declare a new Junction to create new channels and construct new
7 // Join Patterns based on them.
8 let cell = Junction::new();
9
10 // New channel to retrieve the value of the storage cell.
11 let get = cell.recv_channel::<i32>();
12
13 // New channel to update the value of the storage cell.
14 let put = cell.send_channel::<i32>();
15
16 // New channel to swap the value of the storage cell for a new one and
17 // retrieve the value that was just replaced.
18 let swap = cell.bidir_channel::<i32, i32>();
19
20 // New channel that will actually carry the value so that at no point
21 // any given thread will have possession over it so concurrency issues
22 // are avoided by design.
23 let val = cell.send_channel::<i32>();
24
25 // Set up some clones of the above channels we can move over to the
26 // thread in which the function body of the Join Pattern will run.
27 //
28 // Clones of channels work like clones of the std::sync::mpsc::Sender
29 // clones - any message sent from the clone will be received as if
30 // sent from the original.
31 let get_val = val.clone();
32 let put_val = val.clone();
33 let swap_val = val.clone();
34 let val_val = val.clone();
35
36 // Declare a new Join Pattern to update the storage cell value. If
37 // both the put and val channel have sent a message, meaning someone
38 // requested a value update and there is a value to be updated, send
39 // a new val message through one of val's clones that carries the
40 // updated value.
41 cell.when(&put).and(&val).then_do(move |new, _old| {
42 println!(">> put-val pattern fired with new={}!", new);
43 put_val.send(new).unwrap();
44 });
45
46 // Declare a new Join Pattern to retrieve the storage cell value. If
47 // both the get and val channel have sent a message, meaning someone
48 // requested the value and there is a value to be given, return that
49 // value and resend it through one of val's clones so that the value
50 // is still available in future and not just consumed once.
51 cell.when(&val).and_recv(&get).then_do(move |v| {
52 println!(">> val-get pattern fired with v={}!", v);
53
54 get_val.send(v.clone()).unwrap();
55
56 v
57 });
58
59 // Declare a new Join Pattern to swap the storage cell value with a
60 // new one and retrieve the old. Essentially works like a combination
61 // of the previous two Join Patterns, with one crucial distinction:
62 // with this Join Pattern, the update of the value and the retrieval
63 // of the old are atomic, meaning that it is guaranteed that even in
64 // a multithreaded environment with many users accessing the storage
65 // cell, the value retrieved is exactly the value that has been
66 // updated.
67 cell.when(&val).and_bidir(&swap).then_do(move |old, new| {
68 println!(
69 ">> val-swap pattern fired with old={} and new={}!",
70 old, new
71 );
72 swap_val.send(new).unwrap();
73
74 old
75 });
76
77 // Declare a new Join Pattern that mentions the same channel multiple
78 // times, so if the val channel has sent two messages they will be
79 // combined into a single messages sent by a clone of val. This ensures
80 // that eventually, the storage cell will only keep a single value
81 // around.
82 cell.when(&val).and(&val).then_do(move |a, b| {
83 println!(">> val-val pattern fired with a={} and b={}!", a, b);
84 val_val.send(a + b).unwrap();
85 });
86
87 /* End of the Join Pattern setup. */
88
89 // Initialise the storage cell by sending an initial value that
90 // can be picked up in future executions of the above Join Patterns.
91 val.send(1729).unwrap();
92
93 // Request a value update if one is available.
94 put.send(42).unwrap();
95
96 // Send another value that will eventually get combined with the
97 // existing one.
98 val.send(1).unwrap();
99
100 // Request another value update.
101 put.send(22).unwrap();
102
103 // Request the current value of the storage cell and print it.
104 println!("get.recv()={}", get.recv().unwrap());
105
106 // Request a swap of the current value of the storage cell with a new
107 // one and print the old value that is retrieved as a result.
108 println!("swap.send_recv()={}", swap.send_recv(16).unwrap());
109
110 // Request the current value of the storage cell again and print it.
111 println!("get.recv()={}", get.recv().unwrap());
112}Sourcepub fn controller_handle(&mut self) -> Option<ControllerHandle>
pub fn controller_handle(&mut self) -> Option<ControllerHandle>
Return handle to internal Controller if available.
Each Junction has an associated control thread with a Controller
running to handle incoming Packets. This Controller is gracefully
stopped and its thread joined as soon as the Junction goes out of
scope. However, as this is sometimes undesired behavior, the user can
retrieve the handle to the Junction’s Controller and its thread
with this function and stop the Controller at a time of their
choosing. Once this function has executed, the Junction will no
long automatically stop its Controller and join the control thread
upon going out of scope.
Note that this handle can only be retrieved once.
Sourcepub fn send_channel<T>(&self) -> SendChannel<T>
pub fn send_channel<T>(&self) -> SendChannel<T>
Create and return a new SendChannel on this Junction.
The generic parameter T is used to determine the type of values
that can be sent on this channel.
§Panics
Panics if it received an error while trying to receive a new channel ID from the control thread.
Examples found in repository?
4fn main() {
5 // Create a new Junction.
6 let j = Junction::new();
7
8 // Create new channels on the Junction j.
9 let name = j.send_channel::<String>();
10 let value = j.send_channel::<i32>();
11
12 // Declare a new Join Pattern on the Junction using the channels above.
13 j.when(&name).and(&value).then_do(|n, v| { println!("{} {}", n, v); });
14
15 // Send all the required messages for the Join Pattern above to fire.
16 value.send(1729).unwrap();
17 name.send(String::from("Taxi")).unwrap();
18}More examples
3fn main() {
4 /* Start of the Join Pattern setup. */
5
6 // Declare a new Junction to create new channels and construct new
7 // Join Patterns based on them.
8 let cell = Junction::new();
9
10 // New channel to retrieve the value of the storage cell.
11 let get = cell.recv_channel::<i32>();
12
13 // New channel to update the value of the storage cell.
14 let put = cell.send_channel::<i32>();
15
16 // New channel to swap the value of the storage cell for a new one and
17 // retrieve the value that was just replaced.
18 let swap = cell.bidir_channel::<i32, i32>();
19
20 // New channel that will actually carry the value so that at no point
21 // any given thread will have possession over it so concurrency issues
22 // are avoided by design.
23 let val = cell.send_channel::<i32>();
24
25 // Set up some clones of the above channels we can move over to the
26 // thread in which the function body of the Join Pattern will run.
27 //
28 // Clones of channels work like clones of the std::sync::mpsc::Sender
29 // clones - any message sent from the clone will be received as if
30 // sent from the original.
31 let get_val = val.clone();
32 let put_val = val.clone();
33 let swap_val = val.clone();
34 let val_val = val.clone();
35
36 // Declare a new Join Pattern to update the storage cell value. If
37 // both the put and val channel have sent a message, meaning someone
38 // requested a value update and there is a value to be updated, send
39 // a new val message through one of val's clones that carries the
40 // updated value.
41 cell.when(&put).and(&val).then_do(move |new, _old| {
42 println!(">> put-val pattern fired with new={}!", new);
43 put_val.send(new).unwrap();
44 });
45
46 // Declare a new Join Pattern to retrieve the storage cell value. If
47 // both the get and val channel have sent a message, meaning someone
48 // requested the value and there is a value to be given, return that
49 // value and resend it through one of val's clones so that the value
50 // is still available in future and not just consumed once.
51 cell.when(&val).and_recv(&get).then_do(move |v| {
52 println!(">> val-get pattern fired with v={}!", v);
53
54 get_val.send(v.clone()).unwrap();
55
56 v
57 });
58
59 // Declare a new Join Pattern to swap the storage cell value with a
60 // new one and retrieve the old. Essentially works like a combination
61 // of the previous two Join Patterns, with one crucial distinction:
62 // with this Join Pattern, the update of the value and the retrieval
63 // of the old are atomic, meaning that it is guaranteed that even in
64 // a multithreaded environment with many users accessing the storage
65 // cell, the value retrieved is exactly the value that has been
66 // updated.
67 cell.when(&val).and_bidir(&swap).then_do(move |old, new| {
68 println!(
69 ">> val-swap pattern fired with old={} and new={}!",
70 old, new
71 );
72 swap_val.send(new).unwrap();
73
74 old
75 });
76
77 // Declare a new Join Pattern that mentions the same channel multiple
78 // times, so if the val channel has sent two messages they will be
79 // combined into a single messages sent by a clone of val. This ensures
80 // that eventually, the storage cell will only keep a single value
81 // around.
82 cell.when(&val).and(&val).then_do(move |a, b| {
83 println!(">> val-val pattern fired with a={} and b={}!", a, b);
84 val_val.send(a + b).unwrap();
85 });
86
87 /* End of the Join Pattern setup. */
88
89 // Initialise the storage cell by sending an initial value that
90 // can be picked up in future executions of the above Join Patterns.
91 val.send(1729).unwrap();
92
93 // Request a value update if one is available.
94 put.send(42).unwrap();
95
96 // Send another value that will eventually get combined with the
97 // existing one.
98 val.send(1).unwrap();
99
100 // Request another value update.
101 put.send(22).unwrap();
102
103 // Request the current value of the storage cell and print it.
104 println!("get.recv()={}", get.recv().unwrap());
105
106 // Request a swap of the current value of the storage cell with a new
107 // one and print the old value that is retrieved as a result.
108 println!("swap.send_recv()={}", swap.send_recv(16).unwrap());
109
110 // Request the current value of the storage cell again and print it.
111 println!("get.recv()={}", get.recv().unwrap());
112}Sourcepub fn recv_channel<R>(&self) -> RecvChannel<R>
pub fn recv_channel<R>(&self) -> RecvChannel<R>
Create and return a new RecvChannel on this Junction.
The generic parameter R is used to determine the type of values
that can be received on this channel.
§Panics
Panics if it received an error while trying to receive a new channel ID from the control thread.
Examples found in repository?
3fn main() {
4 /* Start of the Join Pattern setup. */
5
6 // Declare a new Junction to create new channels and construct new
7 // Join Patterns based on them.
8 let cell = Junction::new();
9
10 // New channel to retrieve the value of the storage cell.
11 let get = cell.recv_channel::<i32>();
12
13 // New channel to update the value of the storage cell.
14 let put = cell.send_channel::<i32>();
15
16 // New channel to swap the value of the storage cell for a new one and
17 // retrieve the value that was just replaced.
18 let swap = cell.bidir_channel::<i32, i32>();
19
20 // New channel that will actually carry the value so that at no point
21 // any given thread will have possession over it so concurrency issues
22 // are avoided by design.
23 let val = cell.send_channel::<i32>();
24
25 // Set up some clones of the above channels we can move over to the
26 // thread in which the function body of the Join Pattern will run.
27 //
28 // Clones of channels work like clones of the std::sync::mpsc::Sender
29 // clones - any message sent from the clone will be received as if
30 // sent from the original.
31 let get_val = val.clone();
32 let put_val = val.clone();
33 let swap_val = val.clone();
34 let val_val = val.clone();
35
36 // Declare a new Join Pattern to update the storage cell value. If
37 // both the put and val channel have sent a message, meaning someone
38 // requested a value update and there is a value to be updated, send
39 // a new val message through one of val's clones that carries the
40 // updated value.
41 cell.when(&put).and(&val).then_do(move |new, _old| {
42 println!(">> put-val pattern fired with new={}!", new);
43 put_val.send(new).unwrap();
44 });
45
46 // Declare a new Join Pattern to retrieve the storage cell value. If
47 // both the get and val channel have sent a message, meaning someone
48 // requested the value and there is a value to be given, return that
49 // value and resend it through one of val's clones so that the value
50 // is still available in future and not just consumed once.
51 cell.when(&val).and_recv(&get).then_do(move |v| {
52 println!(">> val-get pattern fired with v={}!", v);
53
54 get_val.send(v.clone()).unwrap();
55
56 v
57 });
58
59 // Declare a new Join Pattern to swap the storage cell value with a
60 // new one and retrieve the old. Essentially works like a combination
61 // of the previous two Join Patterns, with one crucial distinction:
62 // with this Join Pattern, the update of the value and the retrieval
63 // of the old are atomic, meaning that it is guaranteed that even in
64 // a multithreaded environment with many users accessing the storage
65 // cell, the value retrieved is exactly the value that has been
66 // updated.
67 cell.when(&val).and_bidir(&swap).then_do(move |old, new| {
68 println!(
69 ">> val-swap pattern fired with old={} and new={}!",
70 old, new
71 );
72 swap_val.send(new).unwrap();
73
74 old
75 });
76
77 // Declare a new Join Pattern that mentions the same channel multiple
78 // times, so if the val channel has sent two messages they will be
79 // combined into a single messages sent by a clone of val. This ensures
80 // that eventually, the storage cell will only keep a single value
81 // around.
82 cell.when(&val).and(&val).then_do(move |a, b| {
83 println!(">> val-val pattern fired with a={} and b={}!", a, b);
84 val_val.send(a + b).unwrap();
85 });
86
87 /* End of the Join Pattern setup. */
88
89 // Initialise the storage cell by sending an initial value that
90 // can be picked up in future executions of the above Join Patterns.
91 val.send(1729).unwrap();
92
93 // Request a value update if one is available.
94 put.send(42).unwrap();
95
96 // Send another value that will eventually get combined with the
97 // existing one.
98 val.send(1).unwrap();
99
100 // Request another value update.
101 put.send(22).unwrap();
102
103 // Request the current value of the storage cell and print it.
104 println!("get.recv()={}", get.recv().unwrap());
105
106 // Request a swap of the current value of the storage cell with a new
107 // one and print the old value that is retrieved as a result.
108 println!("swap.send_recv()={}", swap.send_recv(16).unwrap());
109
110 // Request the current value of the storage cell again and print it.
111 println!("get.recv()={}", get.recv().unwrap());
112}Sourcepub fn bidir_channel<T, R>(&self) -> BidirChannel<T, R>
pub fn bidir_channel<T, R>(&self) -> BidirChannel<T, R>
Create and return a new BidirChannel on this Junction.
The generic parameter T is used to determine the type of values
that can be sent on this channel while R is used to determine
the type of values that can be received on this channel.
§Panics
Panics if it received an error while trying to receive the new channel IDs from the control thread.
Examples found in repository?
3fn main() {
4 /* Start of the Join Pattern setup. */
5
6 // Declare a new Junction to create new channels and construct new
7 // Join Patterns based on them.
8 let cell = Junction::new();
9
10 // New channel to retrieve the value of the storage cell.
11 let get = cell.recv_channel::<i32>();
12
13 // New channel to update the value of the storage cell.
14 let put = cell.send_channel::<i32>();
15
16 // New channel to swap the value of the storage cell for a new one and
17 // retrieve the value that was just replaced.
18 let swap = cell.bidir_channel::<i32, i32>();
19
20 // New channel that will actually carry the value so that at no point
21 // any given thread will have possession over it so concurrency issues
22 // are avoided by design.
23 let val = cell.send_channel::<i32>();
24
25 // Set up some clones of the above channels we can move over to the
26 // thread in which the function body of the Join Pattern will run.
27 //
28 // Clones of channels work like clones of the std::sync::mpsc::Sender
29 // clones - any message sent from the clone will be received as if
30 // sent from the original.
31 let get_val = val.clone();
32 let put_val = val.clone();
33 let swap_val = val.clone();
34 let val_val = val.clone();
35
36 // Declare a new Join Pattern to update the storage cell value. If
37 // both the put and val channel have sent a message, meaning someone
38 // requested a value update and there is a value to be updated, send
39 // a new val message through one of val's clones that carries the
40 // updated value.
41 cell.when(&put).and(&val).then_do(move |new, _old| {
42 println!(">> put-val pattern fired with new={}!", new);
43 put_val.send(new).unwrap();
44 });
45
46 // Declare a new Join Pattern to retrieve the storage cell value. If
47 // both the get and val channel have sent a message, meaning someone
48 // requested the value and there is a value to be given, return that
49 // value and resend it through one of val's clones so that the value
50 // is still available in future and not just consumed once.
51 cell.when(&val).and_recv(&get).then_do(move |v| {
52 println!(">> val-get pattern fired with v={}!", v);
53
54 get_val.send(v.clone()).unwrap();
55
56 v
57 });
58
59 // Declare a new Join Pattern to swap the storage cell value with a
60 // new one and retrieve the old. Essentially works like a combination
61 // of the previous two Join Patterns, with one crucial distinction:
62 // with this Join Pattern, the update of the value and the retrieval
63 // of the old are atomic, meaning that it is guaranteed that even in
64 // a multithreaded environment with many users accessing the storage
65 // cell, the value retrieved is exactly the value that has been
66 // updated.
67 cell.when(&val).and_bidir(&swap).then_do(move |old, new| {
68 println!(
69 ">> val-swap pattern fired with old={} and new={}!",
70 old, new
71 );
72 swap_val.send(new).unwrap();
73
74 old
75 });
76
77 // Declare a new Join Pattern that mentions the same channel multiple
78 // times, so if the val channel has sent two messages they will be
79 // combined into a single messages sent by a clone of val. This ensures
80 // that eventually, the storage cell will only keep a single value
81 // around.
82 cell.when(&val).and(&val).then_do(move |a, b| {
83 println!(">> val-val pattern fired with a={} and b={}!", a, b);
84 val_val.send(a + b).unwrap();
85 });
86
87 /* End of the Join Pattern setup. */
88
89 // Initialise the storage cell by sending an initial value that
90 // can be picked up in future executions of the above Join Patterns.
91 val.send(1729).unwrap();
92
93 // Request a value update if one is available.
94 put.send(42).unwrap();
95
96 // Send another value that will eventually get combined with the
97 // existing one.
98 val.send(1).unwrap();
99
100 // Request another value update.
101 put.send(22).unwrap();
102
103 // Request the current value of the storage cell and print it.
104 println!("get.recv()={}", get.recv().unwrap());
105
106 // Request a swap of the current value of the storage cell with a new
107 // one and print the old value that is retrieved as a result.
108 println!("swap.send_recv()={}", swap.send_recv(16).unwrap());
109
110 // Request the current value of the storage cell again and print it.
111 println!("get.recv()={}", get.recv().unwrap());
112}Sourcepub fn when<T>(&self, send_channel: &SendChannel<T>) -> SendPartialPattern<T>
pub fn when<T>(&self, send_channel: &SendChannel<T>) -> SendPartialPattern<T>
Create new partial Join Pattern starting with a SendChannel.
§Panics
Panics if the supplied SendChannel does not carry the same
JunctionID as this Junction, i.e. has not been created by and is
associated with this Junction.
Examples found in repository?
4fn main() {
5 // Create a new Junction.
6 let j = Junction::new();
7
8 // Create new channels on the Junction j.
9 let name = j.send_channel::<String>();
10 let value = j.send_channel::<i32>();
11
12 // Declare a new Join Pattern on the Junction using the channels above.
13 j.when(&name).and(&value).then_do(|n, v| { println!("{} {}", n, v); });
14
15 // Send all the required messages for the Join Pattern above to fire.
16 value.send(1729).unwrap();
17 name.send(String::from("Taxi")).unwrap();
18}More examples
3fn main() {
4 /* Start of the Join Pattern setup. */
5
6 // Declare a new Junction to create new channels and construct new
7 // Join Patterns based on them.
8 let cell = Junction::new();
9
10 // New channel to retrieve the value of the storage cell.
11 let get = cell.recv_channel::<i32>();
12
13 // New channel to update the value of the storage cell.
14 let put = cell.send_channel::<i32>();
15
16 // New channel to swap the value of the storage cell for a new one and
17 // retrieve the value that was just replaced.
18 let swap = cell.bidir_channel::<i32, i32>();
19
20 // New channel that will actually carry the value so that at no point
21 // any given thread will have possession over it so concurrency issues
22 // are avoided by design.
23 let val = cell.send_channel::<i32>();
24
25 // Set up some clones of the above channels we can move over to the
26 // thread in which the function body of the Join Pattern will run.
27 //
28 // Clones of channels work like clones of the std::sync::mpsc::Sender
29 // clones - any message sent from the clone will be received as if
30 // sent from the original.
31 let get_val = val.clone();
32 let put_val = val.clone();
33 let swap_val = val.clone();
34 let val_val = val.clone();
35
36 // Declare a new Join Pattern to update the storage cell value. If
37 // both the put and val channel have sent a message, meaning someone
38 // requested a value update and there is a value to be updated, send
39 // a new val message through one of val's clones that carries the
40 // updated value.
41 cell.when(&put).and(&val).then_do(move |new, _old| {
42 println!(">> put-val pattern fired with new={}!", new);
43 put_val.send(new).unwrap();
44 });
45
46 // Declare a new Join Pattern to retrieve the storage cell value. If
47 // both the get and val channel have sent a message, meaning someone
48 // requested the value and there is a value to be given, return that
49 // value and resend it through one of val's clones so that the value
50 // is still available in future and not just consumed once.
51 cell.when(&val).and_recv(&get).then_do(move |v| {
52 println!(">> val-get pattern fired with v={}!", v);
53
54 get_val.send(v.clone()).unwrap();
55
56 v
57 });
58
59 // Declare a new Join Pattern to swap the storage cell value with a
60 // new one and retrieve the old. Essentially works like a combination
61 // of the previous two Join Patterns, with one crucial distinction:
62 // with this Join Pattern, the update of the value and the retrieval
63 // of the old are atomic, meaning that it is guaranteed that even in
64 // a multithreaded environment with many users accessing the storage
65 // cell, the value retrieved is exactly the value that has been
66 // updated.
67 cell.when(&val).and_bidir(&swap).then_do(move |old, new| {
68 println!(
69 ">> val-swap pattern fired with old={} and new={}!",
70 old, new
71 );
72 swap_val.send(new).unwrap();
73
74 old
75 });
76
77 // Declare a new Join Pattern that mentions the same channel multiple
78 // times, so if the val channel has sent two messages they will be
79 // combined into a single messages sent by a clone of val. This ensures
80 // that eventually, the storage cell will only keep a single value
81 // around.
82 cell.when(&val).and(&val).then_do(move |a, b| {
83 println!(">> val-val pattern fired with a={} and b={}!", a, b);
84 val_val.send(a + b).unwrap();
85 });
86
87 /* End of the Join Pattern setup. */
88
89 // Initialise the storage cell by sending an initial value that
90 // can be picked up in future executions of the above Join Patterns.
91 val.send(1729).unwrap();
92
93 // Request a value update if one is available.
94 put.send(42).unwrap();
95
96 // Send another value that will eventually get combined with the
97 // existing one.
98 val.send(1).unwrap();
99
100 // Request another value update.
101 put.send(22).unwrap();
102
103 // Request the current value of the storage cell and print it.
104 println!("get.recv()={}", get.recv().unwrap());
105
106 // Request a swap of the current value of the storage cell with a new
107 // one and print the old value that is retrieved as a result.
108 println!("swap.send_recv()={}", swap.send_recv(16).unwrap());
109
110 // Request the current value of the storage cell again and print it.
111 println!("get.recv()={}", get.recv().unwrap());
112}Sourcepub fn when_recv<R>(
&self,
recv_channel: &RecvChannel<R>,
) -> RecvPartialPattern<R>
pub fn when_recv<R>( &self, recv_channel: &RecvChannel<R>, ) -> RecvPartialPattern<R>
Create new partial Join Pattern starting with a RecvChannel.
§Panics
Panics if the supplied RecvChannel does not carry the same
JunctionID as this Junction, i.e. has not been created by and is
associated with this Junction.
Sourcepub fn when_bidir<T, R>(
&self,
bidir_channel: &BidirChannel<T, R>,
) -> BidirPartialPattern<T, R>
pub fn when_bidir<T, R>( &self, bidir_channel: &BidirChannel<T, R>, ) -> BidirPartialPattern<T, R>
Create a new partial Join Pattern starting with a BidirChannel.
§Panics
Panics if the supplied BidirChannel does not carry the same
JunctionID as this Junction, i.e. has not been created by and is
associated with this Junction.