1
1
use super :: MessageInfo ;
2
+ use crate :: ReadOnlyLoanedMessage ;
3
+
4
+ use rosidl_runtime_rs:: Message ;
2
5
3
6
/// A trait for allowed callbacks for subscriptions.
4
7
///
5
8
/// See [`AnySubscriptionCallback`] for a list of possible callback signatures.
6
- pub trait SubscriptionCallback < T , Args > : Send {
9
+ pub trait SubscriptionCallback < T , Args > : Send + ' static
10
+ where
11
+ T : Message ,
12
+ {
7
13
/// Converts the callback into an enum.
8
14
///
9
15
/// User code never needs to call this function.
@@ -13,7 +19,10 @@ pub trait SubscriptionCallback<T, Args>: Send {
13
19
/// An enum capturing the various possible function signatures for subscription callbacks.
14
20
///
15
21
/// The correct enum variant is deduced by the [`SubscriptionCallback`] trait.
16
- pub enum AnySubscriptionCallback < T > {
22
+ pub enum AnySubscriptionCallback < T >
23
+ where
24
+ T : Message ,
25
+ {
17
26
/// A callback with only the message as an argument.
18
27
Regular ( Box < dyn FnMut ( T ) + Send > ) ,
19
28
/// A callback with the message and the message info as arguments.
@@ -22,92 +31,104 @@ pub enum AnySubscriptionCallback<T> {
22
31
Boxed ( Box < dyn FnMut ( Box < T > ) + Send > ) ,
23
32
/// A callback with the boxed message and the message info as arguments.
24
33
BoxedWithMessageInfo ( Box < dyn FnMut ( Box < T > , MessageInfo ) + Send > ) ,
34
+ /// A callback with only the loaned message as an argument.
35
+ #[ allow( clippy:: type_complexity) ]
36
+ Loaned ( Box < dyn for < ' a > FnMut ( ReadOnlyLoanedMessage < ' a , T > ) + Send > ) ,
37
+ /// A callback with the loaned message and the message info as arguments.
38
+ #[ allow( clippy:: type_complexity) ]
39
+ LoanedWithMessageInfo ( Box < dyn for < ' a > FnMut ( ReadOnlyLoanedMessage < ' a , T > , MessageInfo ) + Send > ) ,
25
40
}
26
41
27
42
// We need one implementation per arity. This was inspired by Bevy's systems.
28
43
impl < T , A0 , Func > SubscriptionCallback < T , ( A0 , ) > for Func
29
44
where
30
45
Func : FnMut ( A0 ) + Send + ' static ,
31
- ( A0 , ) : ArgTuple < T , Func = Box < dyn FnMut ( A0 ) + Send > > ,
46
+ ( A0 , ) : ArgTuple < T , Func > ,
47
+ T : Message ,
32
48
{
33
49
fn into_callback ( self ) -> AnySubscriptionCallback < T > {
34
- <( A0 , ) as ArgTuple < T > >:: into_callback_with_args ( Box :: new ( self ) )
50
+ <( A0 , ) as ArgTuple < T , Func > >:: into_callback_with_args ( self )
35
51
}
36
52
}
37
53
38
54
impl < T , A0 , A1 , Func > SubscriptionCallback < T , ( A0 , A1 ) > for Func
39
55
where
40
56
Func : FnMut ( A0 , A1 ) + Send + ' static ,
41
- ( A0 , A1 ) : ArgTuple < T , Func = Box < dyn FnMut ( A0 , A1 ) + Send > > ,
57
+ ( A0 , A1 ) : ArgTuple < T , Func > ,
58
+ T : Message ,
42
59
{
43
60
fn into_callback ( self ) -> AnySubscriptionCallback < T > {
44
- <( A0 , A1 ) as ArgTuple < T > >:: into_callback_with_args ( Box :: new ( self ) )
61
+ <( A0 , A1 ) as ArgTuple < T , Func > >:: into_callback_with_args ( self )
45
62
}
46
63
}
47
64
48
65
// Helper trait for SubscriptionCallback.
49
66
//
50
67
// For each tuple of args, it provides conversion from a function with
51
68
// these args to the correct enum variant.
52
- trait ArgTuple < T > {
53
- type Func ;
54
- fn into_callback_with_args ( func : Self :: Func ) -> AnySubscriptionCallback < T > ;
69
+ trait ArgTuple < T , Func >
70
+ where
71
+ T : Message ,
72
+ {
73
+ fn into_callback_with_args ( func : Func ) -> AnySubscriptionCallback < T > ;
55
74
}
56
75
57
- impl < T > ArgTuple < T > for ( Box < T > , ) {
58
- type Func = Box < dyn FnMut ( Box < T > ) + Send > ;
59
- fn into_callback_with_args ( func : Self :: Func ) -> AnySubscriptionCallback < T > {
60
- AnySubscriptionCallback :: Boxed ( func)
76
+ impl < T , Func > ArgTuple < T , Func > for ( T , )
77
+ where
78
+ T : Message ,
79
+ Func : FnMut ( T ) + Send + ' static ,
80
+ {
81
+ fn into_callback_with_args ( func : Func ) -> AnySubscriptionCallback < T > {
82
+ AnySubscriptionCallback :: Regular ( Box :: new ( func) )
61
83
}
62
84
}
63
85
64
- impl < T > ArgTuple < T > for ( Box < T > , MessageInfo ) {
65
- type Func = Box < dyn FnMut ( Box < T > , MessageInfo ) + Send > ;
66
- fn into_callback_with_args ( func : Self :: Func ) -> AnySubscriptionCallback < T > {
67
- AnySubscriptionCallback :: BoxedWithMessageInfo ( func)
86
+ impl < T , Func > ArgTuple < T , Func > for ( T , MessageInfo )
87
+ where
88
+ T : Message ,
89
+ Func : FnMut ( T , MessageInfo ) + Send + ' static ,
90
+ {
91
+ fn into_callback_with_args ( func : Func ) -> AnySubscriptionCallback < T > {
92
+ AnySubscriptionCallback :: RegularWithMessageInfo ( Box :: new ( func) )
68
93
}
69
94
}
70
95
71
- impl < T > ArgTuple < T > for ( T , ) {
72
- type Func = Box < dyn FnMut ( T ) + Send > ;
73
- fn into_callback_with_args ( func : Self :: Func ) -> AnySubscriptionCallback < T > {
74
- AnySubscriptionCallback :: Regular ( func)
96
+ impl < T , Func > ArgTuple < T , Func > for ( Box < T > , )
97
+ where
98
+ T : Message ,
99
+ Func : FnMut ( Box < T > ) + Send + ' static ,
100
+ {
101
+ fn into_callback_with_args ( func : Func ) -> AnySubscriptionCallback < T > {
102
+ AnySubscriptionCallback :: Boxed ( Box :: new ( func) )
75
103
}
76
104
}
77
105
78
- impl < T > ArgTuple < T > for ( T , MessageInfo ) {
79
- type Func = Box < dyn FnMut ( T , MessageInfo ) + Send > ;
80
- fn into_callback_with_args ( func : Self :: Func ) -> AnySubscriptionCallback < T > {
81
- AnySubscriptionCallback :: RegularWithMessageInfo ( func)
106
+ impl < T , Func > ArgTuple < T , Func > for ( Box < T > , MessageInfo )
107
+ where
108
+ T : Message ,
109
+ Func : FnMut ( Box < T > , MessageInfo ) + Send + ' static ,
110
+ {
111
+ fn into_callback_with_args ( func : Func ) -> AnySubscriptionCallback < T > {
112
+ AnySubscriptionCallback :: BoxedWithMessageInfo ( Box :: new ( func) )
82
113
}
83
114
}
84
115
85
- #[ cfg( test) ]
86
- mod tests {
87
- use super :: * ;
116
+ impl < T , Func > ArgTuple < T , Func > for ( ReadOnlyLoanedMessage < ' _ , T > , )
117
+ where
118
+ T : Message ,
119
+ Func : for < ' b > FnMut ( ReadOnlyLoanedMessage < ' b , T > ) + Send + ' static ,
120
+ {
121
+ fn into_callback_with_args ( func : Func ) -> AnySubscriptionCallback < T > {
122
+ AnySubscriptionCallback :: Loaned ( Box :: new ( func) )
123
+ }
124
+ }
88
125
89
- #[ test]
90
- fn callback_conversion ( ) {
91
- struct Message ;
92
- let cb = |_msg : Message | { } ;
93
- assert ! ( matches!(
94
- cb. into_callback( ) ,
95
- AnySubscriptionCallback :: <Message >:: Regular ( _)
96
- ) ) ;
97
- let cb = |_msg : Message , _info : MessageInfo | { } ;
98
- assert ! ( matches!(
99
- cb. into_callback( ) ,
100
- AnySubscriptionCallback :: <Message >:: RegularWithMessageInfo ( _)
101
- ) ) ;
102
- let cb = |_msg : Box < Message > | { } ;
103
- assert ! ( matches!(
104
- cb. into_callback( ) ,
105
- AnySubscriptionCallback :: <Message >:: Boxed ( _)
106
- ) ) ;
107
- let cb = |_msg : Box < Message > , _info : MessageInfo | { } ;
108
- assert ! ( matches!(
109
- cb. into_callback( ) ,
110
- AnySubscriptionCallback :: <Message >:: BoxedWithMessageInfo ( _)
111
- ) ) ;
126
+ impl < T , Func > ArgTuple < T , Func > for ( ReadOnlyLoanedMessage < ' _ , T > , MessageInfo )
127
+ where
128
+ T : Message ,
129
+ Func : for < ' b > FnMut ( ReadOnlyLoanedMessage < ' b , T > , MessageInfo ) + Send + ' static ,
130
+ {
131
+ fn into_callback_with_args ( func : Func ) -> AnySubscriptionCallback < T > {
132
+ AnySubscriptionCallback :: LoanedWithMessageInfo ( Box :: new ( func) )
112
133
}
113
134
}
0 commit comments