3
3
//
4
4
// SPDX-License-Identifier: MIT OR Apache-2.0
5
5
6
- use crate :: generator:: rust:: get_params_tokens;
6
+ use crate :: generator:: rust:: { get_call_params_tokens , get_params_tokens} ;
7
7
use crate :: {
8
8
generator:: { naming:: qobject:: QObjectNames , rust:: fragment:: GeneratedRustFragment } ,
9
9
parser:: method:: ParsedMethod ,
@@ -31,6 +31,8 @@ pub fn generate_rust_methods(
31
31
cpp_class_name_rust,
32
32
) ;
33
33
34
+ let call_parameters = get_call_params_tokens ( & invokable. parameters ) ;
35
+
34
36
let return_type = & invokable. method . sig . output ;
35
37
36
38
let cfgs = & invokable. cfgs ;
@@ -54,24 +56,38 @@ pub fn generate_rust_methods(
54
56
Some ( quote ! { unsafe } )
55
57
} ;
56
58
57
- GeneratedRustFragment :: from_cxx_item ( parse_quote_spanned ! {
58
- invokable. method. span( ) =>
59
- // Note: extern "Rust" block does not need to be unsafe
60
- #block_safety extern #block_type {
61
- // Note that we are exposing a Rust method on the C++ type to C++
62
- //
63
- // CXX ends up generating the source, then we generate the matching header.
64
- #[ cxx_name = #invokable_ident_cpp]
65
- // Needed for QObjects to have a namespace on their type or extern block
66
- //
67
- // A Namespace from cxx_qt::bridge would be automatically applied to all children
68
- // but to apply it to only certain types, it is needed here too
69
- #cxx_namespace
70
- #( #cfgs) *
71
- #[ doc( hidden) ]
72
- #unsafe_call fn #invokable_ident_rust( #parameter_signatures) #return_type;
73
- }
74
- } )
59
+ let wrapper_fn = if invokable. wrap {
60
+ vec ! [ parse_quote_spanned! {
61
+ invokable. method. span( ) =>
62
+ #unsafe_call fn #invokable_ident_rust( #parameter_signatures) #return_type {
63
+ self . rust( ) . #invokable_ident_rust( #call_parameters)
64
+ }
65
+ } ]
66
+ } else {
67
+ vec ! [ ]
68
+ } ;
69
+
70
+ GeneratedRustFragment {
71
+ cxx_mod_contents : vec ! [ parse_quote_spanned! {
72
+ invokable. method. span( ) =>
73
+ // Note: extern "Rust" block does not need to be unsafe
74
+ #block_safety extern #block_type {
75
+ // Note that we are exposing a Rust method on the C++ type to C++
76
+ //
77
+ // CXX ends up generating the source, then we generate the matching header.
78
+ #[ cxx_name = #invokable_ident_cpp]
79
+ // Needed for QObjects to have a namespace on their type or extern block
80
+ //
81
+ // A Namespace from cxx_qt::bridge would be automatically applied to all children
82
+ // but to apply it to only certain types, it is needed here too
83
+ #cxx_namespace
84
+ #( #cfgs) *
85
+ #[ doc( hidden) ]
86
+ #unsafe_call fn #invokable_ident_rust( #parameter_signatures) #return_type;
87
+ }
88
+ } ] ,
89
+ cxx_qt_mod_contents : wrapper_fn,
90
+ }
75
91
} )
76
92
. collect :: < Vec < _ > > ( ) ;
77
93
@@ -98,10 +114,12 @@ mod tests {
98
114
} ;
99
115
let method3: ForeignItemFn = parse_quote ! {
100
116
#[ cxx_name = "opaqueInvokable" ]
117
+ #[ auto_wrap]
101
118
fn opaque_invokable( self : Pin <& mut MyObject >, param: & QColor ) -> UniquePtr <QColor >;
102
119
} ;
103
120
let method4: ForeignItemFn = parse_quote ! {
104
121
#[ cxx_name = "unsafeInvokable" ]
122
+ #[ auto_wrap]
105
123
unsafe fn unsafe_invokable( self : & MyObject , param: * mut T ) -> * mut T ;
106
124
} ;
107
125
let invokables = vec ! [
@@ -116,7 +134,7 @@ mod tests {
116
134
generate_rust_methods ( & invokables. iter ( ) . collect :: < Vec < _ > > ( ) , & qobject_names) . unwrap ( ) ;
117
135
118
136
assert_eq ! ( generated. cxx_mod_contents. len( ) , 4 ) ;
119
- assert_eq ! ( generated. cxx_qt_mod_contents. len( ) , 0 ) ;
137
+ assert_eq ! ( generated. cxx_qt_mod_contents. len( ) , 2 ) ;
120
138
121
139
// void_invokable
122
140
assert_tokens_eq (
@@ -154,6 +172,15 @@ mod tests {
154
172
} ,
155
173
) ;
156
174
175
+ assert_tokens_eq (
176
+ & generated. cxx_qt_mod_contents [ 0 ] ,
177
+ quote ! {
178
+ fn opaque_invokable( self : Pin <& mut MyObject >, param: & QColor ) -> UniquePtr <QColor > {
179
+ self . rust( ) . opaque_invokable( param)
180
+ }
181
+ } ,
182
+ ) ;
183
+
157
184
// unsafe_invokable
158
185
assert_tokens_eq (
159
186
& generated. cxx_mod_contents [ 3 ] ,
@@ -165,5 +192,14 @@ mod tests {
165
192
}
166
193
} ,
167
194
) ;
195
+
196
+ assert_tokens_eq (
197
+ & generated. cxx_qt_mod_contents [ 1 ] ,
198
+ quote ! {
199
+ unsafe fn unsafe_invokable( self : & MyObject , param: * mut T ) -> * mut T {
200
+ self . rust( ) . unsafe_invokable( param)
201
+ }
202
+ } ,
203
+ ) ;
168
204
}
169
205
}
0 commit comments