Skip to content

Commit 723ba1e

Browse files
Add Transitive casting and testing code (#1252)
* Add Transitive casting and testing code * Add Transitive casting and testing code * Add book entry and rename macro
1 parent 358748d commit 723ba1e

File tree

17 files changed

+304
-155
lines changed

17 files changed

+304
-155
lines changed

book/src/concepts/casting.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ or a `#[base = T]` attribute. See the [attributes documentation](../bridge/attri
1515
1616
## Accessing the base class
1717

18-
To access the methods of a base class in Rust, use the `Upcast` trait like so `use cxx_qt::Upcast;`.
18+
To access the methods of a base class in Rust, use the `Upcast` trait like so `use cxx_qt::casting::Upcast;`.
1919
Objects with base classes can then be accessed with the following methods
2020

2121
| Self Type | Method |
@@ -41,3 +41,17 @@ The child can then be accessed in the same manner, with the following methods
4141
These will return an `Option<T>`, as it is possible that downcasting will fail,
4242
if the type is not actually of the given subclass,
4343
and these also return in the same format as the self type, e.g. `downcast()` returns `Option<&Sub>`, etc...
44+
45+
## Transitive casting
46+
47+
Given 3 types, where there is a grandparent relationship, e.g. that using 2 casts, you can go from A -> B -> C,
48+
CXX-Qt inlcudes a macro for automatically implementing a cast between A and C. This property also extends for longer chains.
49+
For example, if you have a deeply nested set of inheritance, you can quickly generate helpers to cast from your child type to any of its ancestors.
50+
51+
```rust, ignore
52+
use cxx_qt::impl_transitive_cast;
53+
54+
impl_transitive_cast!(A, B, C, D);
55+
```
56+
57+
Will generate casting from A -> C, and A -> D, **provided** A -> B -> C -> D is already implemented.

crates/cxx-qt-gen/src/generator/rust/fragment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl GeneratedRustFragment {
7878
}
7979
}],
8080
cxx_qt_mod_contents: vec![parse_quote! {
81-
impl ::cxx_qt::Upcast<#base_qualified> for #struct_name {
81+
unsafe impl ::cxx_qt::casting::Upcast<#base_qualified> for #struct_name {
8282
unsafe fn upcast_ptr(this: *const Self) -> *const #base_qualified {
8383
#upcast_fn_qualified(this)
8484
}

crates/cxx-qt-gen/test_outputs/cfgs.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ cxx_qt::static_assertions::assert_eq_size!(
677677
cxx_qt::signalhandler::CxxQtSignalHandler<QObjectEnabledCxxQtSignalClosuresignal_enabled>,
678678
[usize; 2]
679679
);
680-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::QObjectEnabled {
680+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::QObjectEnabled {
681681
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
682682
ffi::cxx_qt_ffi_QObjectEnabled_upcastPtr(this)
683683
}
@@ -864,7 +864,7 @@ cxx_qt::static_assertions::assert_eq_size!(
864864
cxx_qt::signalhandler::CxxQtSignalHandler<QObjectDisabledCxxQtSignalClosuresignal_enabled>,
865865
[usize; 2]
866866
);
867-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::QObjectDisabled {
867+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::QObjectDisabled {
868868
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
869869
ffi::cxx_qt_ffi_QObjectDisabled_upcastPtr(this)
870870
}
@@ -895,7 +895,7 @@ impl ::cxx_qt::CxxQtType for ffi::QObjectDisabled {
895895
ffi::cxx_qt_ffi_QObjectDisabled_unsafeRustMut(self)
896896
}
897897
}
898-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::QObjectExternEnabled {
898+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::QObjectExternEnabled {
899899
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
900900
ffi::cxx_qt_ffi_QObjectExternEnabled_upcastPtr(this)
901901
}
@@ -1073,7 +1073,7 @@ cxx_qt::static_assertions::assert_eq_size!(
10731073
>,
10741074
[usize; 2]
10751075
);
1076-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::QObjectExternDisabled {
1076+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::QObjectExternDisabled {
10771077
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
10781078
ffi::cxx_qt_ffi_QObjectExternDisabled_upcastPtr(this)
10791079
}

crates/cxx-qt-gen/test_outputs/inheritance.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ mod inheritance {
130130
type QObject = cxx_qt::QObject;
131131
}
132132
}
133-
impl ::cxx_qt::Upcast<inheritance::QAbstractItemModel> for inheritance::MyObject {
133+
unsafe impl ::cxx_qt::casting::Upcast<inheritance::QAbstractItemModel> for inheritance::MyObject {
134134
unsafe fn upcast_ptr(this: *const Self) -> *const inheritance::QAbstractItemModel {
135135
inheritance::cxx_qt_ffi_MyObject_upcastPtr(this)
136136
}
@@ -158,15 +158,15 @@ impl ::cxx_qt::CxxQtType for inheritance::MyObject {
158158
inheritance::cxx_qt_ffi_MyObject_unsafeRustMut(self)
159159
}
160160
}
161-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for inheritance::QPushButton {
161+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for inheritance::QPushButton {
162162
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
163163
inheritance::cxx_qt_ffi_QPushButton_upcastPtr(this)
164164
}
165165
unsafe fn from_base_ptr(base: *const ::cxx_qt::QObject) -> *const Self {
166166
inheritance::cxx_qt_ffi_QPushButton_downcastPtr(base)
167167
}
168168
}
169-
impl ::cxx_qt::Upcast<inheritance::QPushButton> for inheritance::QPushButtonChild {
169+
unsafe impl ::cxx_qt::casting::Upcast<inheritance::QPushButton> for inheritance::QPushButtonChild {
170170
unsafe fn upcast_ptr(this: *const Self) -> *const inheritance::QPushButton {
171171
inheritance::cxx_qt_ffi_QPushButtonChild_upcastPtr(this)
172172
}

crates/cxx-qt-gen/test_outputs/invokables.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ impl cxx_qt::Threading for ffi::MyObject {
326326
pub struct MyObjectCxxQtThreadQueuedFn {
327327
inner: std::boxed::Box<dyn FnOnce(core::pin::Pin<&mut ffi::MyObject>) + Send>,
328328
}
329-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::MyObject {
329+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::MyObject {
330330
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
331331
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
332332
}

crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ cxx_qt::static_assertions::assert_eq_size!(
659659
cxx_qt::signalhandler::CxxQtSignalHandler<MyObjectCxxQtSignalClosureready>,
660660
[usize; 2]
661661
);
662-
impl ::cxx_qt::Upcast<ffi::QStringListModel> for ffi::MyObject {
662+
unsafe impl ::cxx_qt::casting::Upcast<ffi::QStringListModel> for ffi::MyObject {
663663
unsafe fn upcast_ptr(this: *const Self) -> *const ffi::QStringListModel {
664664
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
665665
}
@@ -839,7 +839,7 @@ cxx_qt::static_assertions::assert_eq_size!(
839839
cxx_qt::signalhandler::CxxQtSignalHandler<SecondObjectCxxQtSignalClosureready>,
840840
[usize; 2]
841841
);
842-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::SecondObject {
842+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::SecondObject {
843843
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
844844
ffi::cxx_qt_ffi_SecondObject_upcastPtr(this)
845845
}
@@ -867,7 +867,7 @@ impl ::cxx_qt::CxxQtType for ffi::SecondObject {
867867
ffi::cxx_qt_ffi_SecondObject_unsafeRustMut(self)
868868
}
869869
}
870-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::MyRustName {
870+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::MyRustName {
871871
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
872872
ffi::cxx_qt_ffi_MyCxxName_upcastPtr(this)
873873
}
@@ -895,15 +895,15 @@ impl ::cxx_qt::CxxQtType for ffi::MyRustName {
895895
ffi::cxx_qt_ffi_MyCxxName_unsafeRustMut(self)
896896
}
897897
}
898-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::QPushButton {
898+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::QPushButton {
899899
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
900900
ffi::cxx_qt_ffi_QPushButton_upcastPtr(this)
901901
}
902902
unsafe fn from_base_ptr(base: *const ::cxx_qt::QObject) -> *const Self {
903903
ffi::cxx_qt_ffi_QPushButton_downcastPtr(base)
904904
}
905905
}
906-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::ExternObject {
906+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::ExternObject {
907907
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
908908
ffi::cxx_qt_ffi_ExternObjectCpp_upcastPtr(this)
909909
}

crates/cxx-qt-gen/test_outputs/properties.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ cxx_qt::static_assertions::assert_eq_size!(
11101110
cxx_qt::signalhandler::CxxQtSignalHandler<MyObjectCxxQtSignalClosuremy_on_changed>,
11111111
[usize; 2]
11121112
);
1113-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::MyObject {
1113+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::MyObject {
11141114
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
11151115
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
11161116
}

crates/cxx-qt-gen/test_outputs/qenum.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ mod ffi {
169169
type QObject = cxx_qt::QObject;
170170
}
171171
}
172-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::MyObject {
172+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::MyObject {
173173
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
174174
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
175175
}
@@ -197,7 +197,7 @@ impl ::cxx_qt::CxxQtType for ffi::MyObject {
197197
ffi::cxx_qt_ffi_MyObject_unsafeRustMut(self)
198198
}
199199
}
200-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::MyRenamedObject {
200+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::MyRenamedObject {
201201
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
202202
ffi::cxx_qt_ffi_CxxName_upcastPtr(this)
203203
}

crates/cxx-qt-gen/test_outputs/signals.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ cxx_qt::static_assertions::assert_eq_size!(
464464
cxx_qt::signalhandler::CxxQtSignalHandler<MyObjectCxxQtSignalClosurenewData>,
465465
[usize; 2]
466466
);
467-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::MyObject {
467+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::MyObject {
468468
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
469469
ffi::cxx_qt_ffi_MyObject_upcastPtr(this)
470470
}
@@ -492,7 +492,7 @@ impl ::cxx_qt::CxxQtType for ffi::MyObject {
492492
ffi::cxx_qt_ffi_MyObject_unsafeRustMut(self)
493493
}
494494
}
495-
impl ::cxx_qt::Upcast<::cxx_qt::QObject> for ffi::QTimer {
495+
unsafe impl ::cxx_qt::casting::Upcast<::cxx_qt::QObject> for ffi::QTimer {
496496
unsafe fn upcast_ptr(this: *const Self) -> *const ::cxx_qt::QObject {
497497
ffi::cxx_qt_ffi_QTimer_upcastPtr(this)
498498
}

crates/cxx-qt-lib/src/core/qstringlist.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use crate::{QList, QString};
66
use core::mem::MaybeUninit;
77
use cxx::{type_id, ExternType};
8-
use cxx_qt::Upcast;
8+
use cxx_qt::casting::Upcast;
99
use std::fmt;
1010
use std::ops::{Deref, DerefMut};
1111

@@ -204,7 +204,7 @@ impl DerefMut for QStringList {
204204
}
205205
}
206206

207-
impl Upcast<QList<QString>> for QStringList {
207+
unsafe impl Upcast<QList<QString>> for QStringList {
208208
unsafe fn upcast_ptr(this: *const Self) -> *const QList<QString> {
209209
ffi::upcast_qstringlist(this)
210210
}

0 commit comments

Comments
 (0)