@@ -38,6 +38,12 @@ pub struct RouterProxy {
38
38
comm : Mutex < RouterProxyComm > ,
39
39
}
40
40
41
+ impl Drop for RouterProxy {
42
+ fn drop ( & mut self ) {
43
+ self . shutdown ( ) ;
44
+ }
45
+ }
46
+
41
47
#[ allow( clippy:: new_without_default) ]
42
48
impl RouterProxy {
43
49
pub fn new ( ) -> RouterProxy {
@@ -62,11 +68,7 @@ impl RouterProxy {
62
68
63
69
/// Add a new (receiver, callback) pair to the router, and send a wakeup message
64
70
/// to the router.
65
- ///
66
- /// Consider using [add_typed_route](Self::add_typed_route) instead, which prevents
67
- /// mismatches between the receiver and callback types.
68
- #[ deprecated( since = "0.19.0" , note = "please use 'add_typed_route' instead" ) ]
69
- pub fn add_route ( & self , receiver : OpaqueIpcReceiver , callback : RouterHandler ) {
71
+ fn add_route ( & self , receiver : OpaqueIpcReceiver , callback : RouterHandler ) {
70
72
let comm = self . comm . lock ( ) . unwrap ( ) ;
71
73
72
74
if comm. shutdown {
@@ -81,11 +83,11 @@ impl RouterProxy {
81
83
82
84
/// Add a new `(receiver, callback)` pair to the router, and send a wakeup message
83
85
/// to the router.
84
- ///
85
- /// Unlike [add_route](Self::add_route) this method is strongly typed and guarantees
86
- /// that the ` receiver` and the `callback` use the same message type.
87
- pub fn add_typed_route < T > ( & self , receiver : IpcReceiver < T > , mut callback : TypedRouterHandler < T > )
88
- where
86
+ pub fn add_typed_route < T > (
87
+ & self ,
88
+ receiver : IpcReceiver < T > ,
89
+ mut callback : TypedRouterMultiHandler < T > ,
90
+ ) where
89
91
T : Serialize + for < ' de > Deserialize < ' de > + ' static ,
90
92
{
91
93
// Before passing the message on to the callback, turn it into the appropriate type
@@ -94,8 +96,31 @@ impl RouterProxy {
94
96
callback ( typed_message)
95
97
} ;
96
98
97
- #[ allow( deprecated) ]
98
- self . add_route ( receiver. to_opaque ( ) , Box :: new ( modified_callback) ) ;
99
+ self . add_route (
100
+ receiver. to_opaque ( ) ,
101
+ RouterHandler :: Multi ( Box :: new ( modified_callback) ) ,
102
+ ) ;
103
+ }
104
+
105
+ /// Add a new `(receiver, callback)` pair to the router, and send a wakeup message
106
+ /// to the router.
107
+ pub fn add_typed_one_shot_route < T > (
108
+ & self ,
109
+ receiver : IpcReceiver < T > ,
110
+ callback : TypedRouterOneShotHandler < T > ,
111
+ ) where
112
+ T : Serialize + for < ' de > Deserialize < ' de > + ' static ,
113
+ {
114
+ // Before passing the message on to the callback, turn it into the appropriate type
115
+ let modified_callback = move |msg : IpcMessage | {
116
+ let typed_message = msg. to :: < T > ( ) ;
117
+ callback ( typed_message)
118
+ } ;
119
+
120
+ self . add_route (
121
+ receiver. to_opaque ( ) ,
122
+ RouterHandler :: Once ( Some ( Box :: new ( modified_callback) ) ) ,
123
+ ) ;
99
124
}
100
125
101
126
/// Send a shutdown message to the router containing a ACK sender,
@@ -226,7 +251,16 @@ impl Router {
226
251
} ,
227
252
// Event from one of our registered receivers, call callback.
228
253
IpcSelectionResult :: MessageReceived ( id, message) => {
229
- self . handlers . get_mut ( & id) . unwrap ( ) ( message)
254
+ match self . handlers . get_mut ( & id) . unwrap ( ) {
255
+ RouterHandler :: Once ( handler) => {
256
+ if let Some ( handler) = handler. take ( ) {
257
+ ( handler) ( message) ;
258
+ }
259
+ } ,
260
+ RouterHandler :: Multi ( ref mut handler) => {
261
+ ( handler) ( message) ;
262
+ } ,
263
+ }
230
264
} ,
231
265
IpcSelectionResult :: ChannelClosed ( id) => {
232
266
let _ = self . handlers . remove ( & id) . unwrap ( ) ;
@@ -246,7 +280,18 @@ enum RouterMsg {
246
280
}
247
281
248
282
/// Function to call when a new event is received from the corresponding receiver.
249
- pub type RouterHandler = Box < dyn FnMut ( IpcMessage ) + Send > ;
283
+ pub type RouterMultiHandler = Box < dyn FnMut ( IpcMessage ) + Send > ;
284
+
285
+ /// Function to call the first time that a message is received from the corresponding receiver.
286
+ pub type RouterOneShotHandler = Box < dyn FnOnce ( IpcMessage ) + Send > ;
287
+
288
+ enum RouterHandler {
289
+ Once ( Option < RouterOneShotHandler > ) ,
290
+ Multi ( RouterMultiHandler ) ,
291
+ }
292
+
293
+ /// Like [RouterMultiHandler] but includes the type that will be passed to the callback
294
+ pub type TypedRouterMultiHandler < T > = Box < dyn FnMut ( Result < T , bincode:: Error > ) + Send > ;
250
295
251
- /// Like [RouterHandler ] but includes the type that will be passed to the callback
252
- pub type TypedRouterHandler < T > = Box < dyn FnMut ( Result < T , bincode:: Error > ) + Send > ;
296
+ /// Like [RouterOneShotHandler ] but includes the type that will be passed to the callback
297
+ pub type TypedRouterOneShotHandler < T > = Box < dyn FnOnce ( Result < T , bincode:: Error > ) + Send > ;
0 commit comments