Skip to content

Commit

Permalink
Implement basic casting for some lib types
Browse files Browse the repository at this point in the history
  • Loading branch information
BenFordTytherington committed Feb 7, 2025
1 parent f6c1f8c commit c60cdfe
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 20 deletions.
12 changes: 0 additions & 12 deletions crates/cxx-qt-lib/src/core/qstringlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,6 @@ static_assert(QTypeInfo<QStringList>::isRelocatable);
namespace rust {
namespace cxxqtlib1 {

const QList<QString>&
qstringlistAsQListQStringRef(const QStringList& list)
{
return static_cast<const QList<QString>&>(list);
}

QList<QString>&
qstringlistAsQListQStringRef(QStringList& list)
{
return static_cast<QList<QString>&>(list);
}

QStringList
qstringlistFromQListQString(const QList<QString>& list)
{
Expand Down
35 changes: 28 additions & 7 deletions crates/cxx-qt-lib/src/core/qstringlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// SPDX-FileContributor: Andrew Hayzen <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
use crate::core::qstringlist::ffi::{downcast_qlist_qstring, upcast_qstringlist, QList_QString};
use crate::{QList, QString};
use core::mem::MaybeUninit;
use cxx::{type_id, ExternType};
use cxx_qt::Upcast;
use std::ops::{Deref, DerefMut};

#[cxx::bridge]
Expand All @@ -25,6 +27,20 @@ mod ffi {
include!("cxx-qt-lib/qstringlist.h");
type QStringList = super::QStringList;

include!("cxx-qt/casting.h");

#[doc(hidden)]
#[rust_name = "upcast_qstringlist"]
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn upcast(thiz: *const QStringList) -> *const QList_QString;

#[doc(hidden)]
#[rust_name = "downcast_qlist_qstring"]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn downcast(base: *const QList_QString) -> *const QStringList;

/// Returns true if the list contains the string str; otherwise returns false.
fn contains(self: &QStringList, str: &QString, cs: CaseSensitivity) -> bool;

Expand Down Expand Up @@ -80,11 +96,6 @@ mod ffi {

#[namespace = "rust::cxxqtlib1"]
unsafe extern "C++" {
#[doc(hidden)]
#[rust_name = "qstringlist_as_qlist_qstring_ref"]
fn qstringlistAsQListQStringRef(list: &QStringList) -> &QList_QString;
#[rust_name = "qstringlist_as_qlist_qstring_ref_mut"]
fn qstringlistAsQListQStringRef(list: &mut QStringList) -> &mut QList_QString;
#[doc(hidden)]
#[rust_name = "qstringlist_from_qlist_qstring"]
fn qstringlistFromQListQString(list: &QList_QString) -> QStringList;
Expand Down Expand Up @@ -184,13 +195,23 @@ impl Deref for QStringList {
type Target = QList<QString>;

fn deref(&self) -> &Self::Target {
ffi::qstringlist_as_qlist_qstring_ref(self)
self.upcast()
}
}

impl DerefMut for QStringList {
fn deref_mut(&mut self) -> &mut Self::Target {
ffi::qstringlist_as_qlist_qstring_ref_mut(self)
self.upcast_mut()
}
}

impl Upcast<QList_QString> for QStringList {
unsafe fn upcast_ptr(this: *const Self) -> *const QList_QString {
upcast_qstringlist(this)
}

unsafe fn from_base_ptr(base: *const QList_QString) -> *const Self {
downcast_qlist_qstring(base)
}
}

Expand Down
32 changes: 31 additions & 1 deletion crates/cxx-qt-lib/src/gui/qguiapplication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use crate::{QByteArray, QFont, QString, QStringList, QVector};
use core::pin::Pin;
use cxx_qt::Upcast;

#[cxx::bridge]
mod ffi {
Expand All @@ -23,6 +24,23 @@ mod ffi {

include!("cxx-qt-lib/qguiapplication.h");
type QGuiApplication;

include!("cxx-qt-lib/qcoreapplication.h");
type QCoreApplication;

include!("cxx-qt/casting.h");

#[doc(hidden)]
#[rust_name = "upcast_qguiapplication"]
#[cxx_name = "upcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn upcast(thiz: *const QGuiApplication) -> *const QCoreApplication;

#[doc(hidden)]
#[rust_name = "downcast_qcoreapplication"]
#[cxx_name = "downcastPtr"]
#[namespace = "rust::cxxqt1"]
unsafe fn downcast(base: *const QCoreApplication) -> *const QGuiApplication;
}

#[namespace = "rust::cxxqtlib1"]
Expand Down Expand Up @@ -98,7 +116,19 @@ mod ffi {
impl UniquePtr<QGuiApplication> {}
}

pub use ffi::QGuiApplication;
pub use ffi::{
downcast_qcoreapplication, upcast_qguiapplication, QCoreApplication, QGuiApplication,
};

impl Upcast<QCoreApplication> for QGuiApplication {
unsafe fn upcast_ptr(this: *const Self) -> *const QCoreApplication {
upcast_qguiapplication(this)
}

unsafe fn from_base_ptr(base: *const QCoreApplication) -> *const Self {
downcast_qcoreapplication(base)
}
}

impl QGuiApplication {
/// Prepends path to the beginning of the library path list,
Expand Down
25 changes: 25 additions & 0 deletions crates/cxx-qt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,31 @@ pub trait Downcast: Sized {
}
}
}

/// try Downcast mutably to a subclass of this, given that the subclass upcasts to this type
fn downcast_mut<Sub: Upcast<Self>>(&mut self) -> Option<&mut Sub> {
unsafe {
let ptr = Sub::from_base_ptr(self as *const Self) as *mut Sub;
if ptr.is_null() {
None
} else {
Some(&mut *ptr)
}
}
}

/// try Downcast a pin to a pinned subclass of this, given that the subclass upcasts to this type
fn downcast_pin<Sub: Upcast<Self>>(self: Pin<&mut Self>) -> Option<Pin<&mut Sub>> {
let this = self.deref() as *const Self;
unsafe {
let ptr = Sub::from_base_ptr(this) as *mut Sub;
if ptr.is_null() {
None
} else {
Some(Pin::new_unchecked(&mut *ptr))
}
}
}
}

impl<T: Sized> Downcast for T {}
Expand Down

0 comments on commit c60cdfe

Please sign in to comment.