Skip to content

Commit ef06ce5

Browse files
committed
cxx-qt-gen: remove wrapper method for C++ -> Rust properties
This then avoids us needing to generate Rust methods with fully qualified types on the Rust side and removes a load of generation. Related to #404
1 parent d14ae73 commit ef06ce5

File tree

13 files changed

+193
-218
lines changed

13 files changed

+193
-218
lines changed

crates/cxx-qt-gen/src/generator/cpp/property/getter.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,22 @@ pub fn generate(
2727
{qobject_ident}::{ident_getter}() const
2828
{{
2929
{rust_obj_guard}
30-
return m_rustObj->{ident_getter}(*this);
30+
return {ident_getter_wrapper}();
3131
}}
3232
"#,
3333
return_cxx_ty = cxx_ty.as_cxx_ty(),
3434
ident_getter = idents.getter.cpp.to_string(),
35+
ident_getter_wrapper = idents.getter_wrapper.cpp.to_string(),
3536
qobject_ident = qobject_ident,
3637
rust_obj_guard = lock_guard.unwrap_or_default(),
3738
),
3839
}
3940
}
41+
42+
pub fn generate_wrapper(idents: &QPropertyName, cxx_ty: &CppType) -> CppFragment {
43+
CppFragment::Header(format!(
44+
"{return_cxx_ty} const& {ident_getter_wrapper}() const noexcept;",
45+
return_cxx_ty = cxx_ty.as_cxx_ty(),
46+
ident_getter_wrapper = idents.getter_wrapper.cpp
47+
))
48+
}

crates/cxx-qt-gen/src/generator/cpp/property/mod.rs

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,18 @@ pub fn generate_cpp_properties(
3737
&cxx_ty,
3838
lock_guard,
3939
));
40+
generated
41+
.private_methods
42+
.push(getter::generate_wrapper(&idents, &cxx_ty));
4043
generated.methods.push(setter::generate(
4144
&idents,
4245
&qobject_ident,
4346
&cxx_ty,
4447
lock_guard,
4548
));
49+
generated
50+
.private_methods
51+
.push(setter::generate_wrapper(&idents, &cxx_ty));
4652
signals.push(signal::generate(&idents, qobject_idents));
4753
}
4854

@@ -109,7 +115,7 @@ mod tests {
109115
MyObject::getTrivialProperty() const
110116
{
111117
// ::std::lock_guard
112-
return m_rustObj->getTrivialProperty(*this);
118+
return getTrivialPropertyWrapper();
113119
}
114120
"#}
115121
);
@@ -130,7 +136,7 @@ mod tests {
130136
MyObject::setTrivialProperty(::std::int32_t const& value)
131137
{
132138
// ::std::lock_guard
133-
m_rustObj->setTrivialProperty(*this, value);
139+
setTrivialPropertyWrapper(value);
134140
}
135141
"#}
136142
);
@@ -151,7 +157,7 @@ mod tests {
151157
MyObject::getOpaqueProperty() const
152158
{
153159
// ::std::lock_guard
154-
return m_rustObj->getOpaqueProperty(*this);
160+
return getOpaquePropertyWrapper();
155161
}
156162
"#}
157163
);
@@ -172,7 +178,7 @@ mod tests {
172178
MyObject::setOpaqueProperty(::std::unique_ptr<QColor> const& value)
173179
{
174180
// ::std::lock_guard
175-
m_rustObj->setOpaqueProperty(*this, value);
181+
setOpaquePropertyWrapper(value);
176182
}
177183
"#}
178184
);
@@ -242,6 +248,48 @@ mod tests {
242248
}
243249
"#}
244250
);
251+
252+
// private methods
253+
assert_eq!(generated.private_methods.len(), 4);
254+
let header = if let CppFragment::Header(header) = &generated.private_methods[0] {
255+
header
256+
} else {
257+
panic!("Expected header")
258+
};
259+
assert_str_eq!(
260+
header,
261+
"::std::int32_t const& getTrivialPropertyWrapper() const noexcept;"
262+
);
263+
264+
let header = if let CppFragment::Header(header) = &generated.private_methods[1] {
265+
header
266+
} else {
267+
panic!("Expected header")
268+
};
269+
assert_str_eq!(
270+
header,
271+
"void setTrivialPropertyWrapper(::std::int32_t value) noexcept;"
272+
);
273+
274+
let header = if let CppFragment::Header(header) = &generated.private_methods[2] {
275+
header
276+
} else {
277+
panic!("Expected header")
278+
};
279+
assert_str_eq!(
280+
header,
281+
"::std::unique_ptr<QColor> const& getOpaquePropertyWrapper() const noexcept;"
282+
);
283+
284+
let header = if let CppFragment::Header(header) = &generated.private_methods[3] {
285+
header
286+
} else {
287+
panic!("Expected header")
288+
};
289+
assert_str_eq!(
290+
header,
291+
"void setOpaquePropertyWrapper(::std::unique_ptr<QColor> value) noexcept;"
292+
);
245293
}
246294

247295
#[test]
@@ -284,7 +332,7 @@ mod tests {
284332
MyObject::getMappedProperty() const
285333
{
286334
// ::std::lock_guard
287-
return m_rustObj->getMappedProperty(*this);
335+
return getMappedPropertyWrapper();
288336
}
289337
"#}
290338
);
@@ -302,7 +350,7 @@ mod tests {
302350
MyObject::setMappedProperty(A1 const& value)
303351
{
304352
// ::std::lock_guard
305-
m_rustObj->setMappedProperty(*this, value);
353+
setMappedPropertyWrapper(value);
306354
}
307355
"#}
308356
);
@@ -338,5 +386,24 @@ mod tests {
338386
}
339387
"#}
340388
);
389+
390+
// private methods
391+
assert_eq!(generated.private_methods.len(), 2);
392+
let header = if let CppFragment::Header(header) = &generated.private_methods[0] {
393+
header
394+
} else {
395+
panic!("Expected header")
396+
};
397+
assert_str_eq!(
398+
header,
399+
"A1 const& getMappedPropertyWrapper() const noexcept;"
400+
);
401+
402+
let header = if let CppFragment::Header(header) = &generated.private_methods[1] {
403+
header
404+
} else {
405+
panic!("Expected header")
406+
};
407+
assert_str_eq!(header, "void setMappedPropertyWrapper(A1 value) noexcept;");
341408
}
342409
}

crates/cxx-qt-gen/src/generator/cpp/property/setter.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,24 @@ pub fn generate(
2727
{qobject_ident}::{ident_setter}({cxx_ty} const& value)
2828
{{
2929
{rust_obj_guard}
30-
m_rustObj->{ident_setter}(*this, value);
30+
{ident_setter_wrapper}(value);
3131
}}
3232
"#,
3333
cxx_ty = cxx_ty.as_cxx_ty(),
3434
ident_setter = idents.setter.cpp,
35+
ident_setter_wrapper = idents.setter_wrapper.cpp.to_string(),
3536
qobject_ident = qobject_ident,
3637
rust_obj_guard = lock_guard.unwrap_or_default(),
3738
},
3839
}
3940
}
41+
42+
pub fn generate_wrapper(idents: &QPropertyName, cxx_ty: &CppType) -> CppFragment {
43+
CppFragment::Header(format!(
44+
// Note that we pass T not const T& to Rust so that it is by-value
45+
// https://github.com/KDAB/cxx-qt/issues/463
46+
"void {ident_setter_wrapper}({cxx_ty} value) noexcept;",
47+
cxx_ty = cxx_ty.as_cxx_ty(),
48+
ident_setter_wrapper = idents.setter_wrapper.cpp
49+
))
50+
}

crates/cxx-qt-gen/src/generator/naming/property.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,22 @@ use syn::Ident;
1212
pub struct QPropertyName {
1313
pub name: CombinedIdent,
1414
pub getter: CombinedIdent,
15+
pub getter_wrapper: CombinedIdent,
1516
pub setter: CombinedIdent,
17+
pub setter_wrapper: CombinedIdent,
1618
pub notify: CombinedIdent,
1719
}
1820

1921
impl From<&Ident> for QPropertyName {
2022
fn from(ident: &Ident) -> Self {
23+
let getter = CombinedIdent::getter_from_property(ident.clone());
24+
let setter = CombinedIdent::setter_from_property(ident);
2125
Self {
2226
name: CombinedIdent::from_property(ident.clone()),
23-
getter: CombinedIdent::getter_from_property(ident.clone()),
24-
setter: CombinedIdent::setter_from_property(ident),
27+
getter_wrapper: CombinedIdent::wrapper_from_combined_property(&getter),
28+
getter,
29+
setter_wrapper: CombinedIdent::wrapper_from_combined_property(&setter),
30+
setter,
2531
notify: CombinedIdent::notify_from_property(ident),
2632
}
2733
}
@@ -67,6 +73,14 @@ impl CombinedIdent {
6773
rust: ident,
6874
}
6975
}
76+
77+
/// For a given ident generate the Rust and C++ wrapper names
78+
fn wrapper_from_combined_property(ident: &CombinedIdent) -> Self {
79+
Self {
80+
cpp: format_ident!("{}Wrapper", ident.cpp),
81+
rust: format_ident!("{}_wrapper", ident.rust),
82+
}
83+
}
7084
}
7185

7286
#[cfg(test)]

crates/cxx-qt-gen/src/generator/rust/property/getter.rs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,26 @@ pub fn generate(
1616
ty: &Type,
1717
) -> RustFragmentPair {
1818
let cpp_class_name_rust = &qobject_idents.cpp_class.rust;
19-
let rust_struct_name_rust = &qobject_idents.rust_struct.rust;
20-
let getter_cpp = idents.getter.cpp.to_string();
19+
let getter_wrapper_cpp = idents.getter_wrapper.cpp.to_string();
2120
let getter_rust = &idents.getter.rust;
2221
let ident = &idents.name.rust;
2322
let ident_str = ident.to_string();
2423

2524
RustFragmentPair {
2625
cxx_bridge: vec![quote! {
2726
extern "Rust" {
28-
#[cxx_name = #getter_cpp]
29-
unsafe fn #getter_rust<'a>(self: &'a #rust_struct_name_rust, cpp: &'a #cpp_class_name_rust) -> &'a #ty;
27+
#[cxx_name = #getter_wrapper_cpp]
28+
unsafe fn #getter_rust<'a>(self: &'a #cpp_class_name_rust) -> &'a #ty;
3029
}
3130
}],
32-
implementation: vec![
33-
quote! {
34-
impl #rust_struct_name_rust {
35-
#[doc(hidden)]
36-
pub fn #getter_rust<'a>(&'a self, cpp: &'a #cpp_class_name_rust) -> &'a #ty {
37-
cpp.#getter_rust()
38-
}
31+
implementation: vec![quote! {
32+
impl #cpp_class_name_rust {
33+
#[doc = "Getter for the Q_PROPERTY "]
34+
#[doc = #ident_str]
35+
pub fn #getter_rust(&self) -> &#ty {
36+
&self.#ident
3937
}
40-
},
41-
quote! {
42-
impl #cpp_class_name_rust {
43-
#[doc = "Getter for the Q_PROPERTY "]
44-
#[doc = #ident_str]
45-
pub fn #getter_rust(&self) -> &#ty {
46-
&self.#ident
47-
}
48-
}
49-
},
50-
],
38+
}
39+
}],
5140
}
5241
}

0 commit comments

Comments
 (0)