From cf3e8764144a8b81ee062d5d4557f45711fb895f Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Thu, 28 Mar 2024 16:34:55 +0000 Subject: [PATCH] WIP: qtypes: add support for Qt alias types that don't match Some times don't match the Rust types so add these missing types. Closes #882 --- crates/cxx-qt-lib/build.rs | 2 + crates/cxx-qt-lib/include/core/qtypes.h | 44 ++++++ crates/cxx-qt-lib/src/core/mod.rs | 3 + crates/cxx-qt-lib/src/core/qtypes.cpp | 81 +++++++++++ crates/cxx-qt-lib/src/core/qtypes.rs | 182 ++++++++++++++++++++++++ 5 files changed, 312 insertions(+) create mode 100644 crates/cxx-qt-lib/include/core/qtypes.h create mode 100644 crates/cxx-qt-lib/src/core/qtypes.cpp create mode 100644 crates/cxx-qt-lib/src/core/qtypes.rs diff --git a/crates/cxx-qt-lib/build.rs b/crates/cxx-qt-lib/build.rs index b6006a02c..f3fde01a0 100644 --- a/crates/cxx-qt-lib/build.rs +++ b/crates/cxx-qt-lib/build.rs @@ -147,6 +147,7 @@ fn main() { "core/qstringlist", "core/qt", "core/qtime", + "core/qtypes", "core/qurl", "core/qvariant/mod", "core/qvariant/qvariant_bool", @@ -271,6 +272,7 @@ fn main() { "core/qstring", "core/qstringlist", "core/qtime", + "core/qtypes", "core/qurl", "core/qvariant/qvariant", "core/qvector/qvector", diff --git a/crates/cxx-qt-lib/include/core/qtypes.h b/crates/cxx-qt-lib/include/core/qtypes.h new file mode 100644 index 000000000..e2402e382 --- /dev/null +++ b/crates/cxx-qt-lib/include/core/qtypes.h @@ -0,0 +1,44 @@ +// clang-format off +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 +#pragma once + +#include + +#include + +#include "rust/cxx.h" + +namespace rust { +namespace cxxqtlib1 { + +::qint64 +qint64FromI64(::std::int64_t value); +::std::int64_t +qint64IntoI64(::qint64 value); + +::qintptr +qintptrFromIsize(::rust::isize value); +::rust::isize +qintptrIntoIsize(qintptr value); + +::quint64 +quint64FromU64(::std::uint64_t value); +::std::uint64_t +quint64IntoU64(::quint64 value); + +::quintptr +quintptrFromUsize(::rust::usize value); +::rust::usize +quintptrIntoUsize(quintptr value); + +::qsizetype +qsizetypeFromIsize(::rust::isize value); +::rust::isize +qsizetypeIntoIsize(qsizetype value); + +} +} diff --git a/crates/cxx-qt-lib/src/core/mod.rs b/crates/cxx-qt-lib/src/core/mod.rs index a2e9bfa33..cf1e93d6a 100644 --- a/crates/cxx-qt-lib/src/core/mod.rs +++ b/crates/cxx-qt-lib/src/core/mod.rs @@ -83,6 +83,9 @@ pub use qt::{ mod qtime; pub use qtime::QTime; +mod qtypes; +pub use qtypes::{QInt64, QIntPtr, QSizeType, QUInt64, QUIntPtr}; + #[cfg(not(target_os = "emscripten"))] mod qtimezone; #[cfg(not(target_os = "emscripten"))] diff --git a/crates/cxx-qt-lib/src/core/qtypes.cpp b/crates/cxx-qt-lib/src/core/qtypes.cpp new file mode 100644 index 000000000..619aca727 --- /dev/null +++ b/crates/cxx-qt-lib/src/core/qtypes.cpp @@ -0,0 +1,81 @@ +// clang-format off +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 +#include "cxx-qt-lib/qtypes.h" + +#include "cxx-qt-lib/assertion_utils.h" + +assert_alignment_and_size(qint64, { ::std::int64_t a0; }); +assert_alignment_and_size(qintptr, { ::std::intptr_t a0; }); +assert_alignment_and_size(quint64, { ::std::uint64_t a0; }); +assert_alignment_and_size(quintptr, { ::std::uintptr_t a0; }); +assert_alignment_and_size(qsizetype, { ::std::size_t a0; }); + +namespace rust { +namespace cxxqtlib1 { + +::qint64 +qint64FromI64(::std::int64_t value) +{ + return static_cast<::qint64>(value); +} + +::std::int64_t +qint64IntoI64(::qint64 value) +{ + return static_cast<::std::int64_t>(value); +} + +::qintptr +qintptrFromIsize(::rust::isize value) +{ + return static_cast<::qintptr>(value); +} + +::rust::isize +qintptrIntoIsize(::qintptr value) +{ + return static_cast<::rust::isize>(value); +} + +::quint64 +quint64FromU64(::std::uint64_t value) +{ + return static_cast<::quint64>(value); +} + +::std::uint64_t +quint64IntoU64(::quint64 value) +{ + return static_cast<::std::uint64_t>(value); +} + +::quintptr +quintptrFromUsize(::rust::usize value) +{ + return static_cast<::quintptr>(value); +} + +::rust::usize +quintptrIntoUsize(::quintptr value) +{ + return static_cast<::rust::usize>(value); +} + +::qsizetype +qsizetypeFromIsize(::rust::isize value) +{ + return static_cast<::qsizetype>(value); +} + +::rust::isize +qsizetypeIntoIsize(::qsizetype value) +{ + return static_cast<::rust::isize>(value); +} + +} +} diff --git a/crates/cxx-qt-lib/src/core/qtypes.rs b/crates/cxx-qt-lib/src/core/qtypes.rs new file mode 100644 index 000000000..982120066 --- /dev/null +++ b/crates/cxx-qt-lib/src/core/qtypes.rs @@ -0,0 +1,182 @@ +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use cxx::{type_id, ExternType}; +use std::mem::MaybeUninit; + +#[cxx::bridge] +mod ffi { + unsafe extern "C++" { + include!("cxx-qt-lib/qtypes.h"); + + #[cxx_name = "qint64"] + type QInt64 = super::QInt64; + + #[cxx_name = "qintptr"] + type QIntPtr = super::QIntPtr; + + #[cxx_name = "quint64"] + type QUInt64 = super::QUInt64; + + #[cxx_name = "quintptr"] + type QUIntPtr = super::QUIntPtr; + + #[cxx_name = "qsizetype"] + type QSizeType = super::QSizeType; + } + + #[namespace = "rust::cxxqtlib1"] + unsafe extern "C++" { + #[rust_name = "qint64_from_i64"] + fn qint64FromI64(value: i64) -> QInt64; + #[rust_name = "qint64_into_i64"] + fn qint64IntoI64(value: QInt64) -> i64; + + #[rust_name = "qintptr_from_isize"] + fn qintptrFromIsize(value: isize) -> QIntPtr; + #[rust_name = "qintptr_into_isize"] + fn qintptrIntoIsize(value: QIntPtr) -> isize; + + #[rust_name = "quint64_from_u64"] + fn quint64FromU64(value: u64) -> QUInt64; + #[rust_name = "quint64_into_u64"] + fn quint64IntoU64(value: QUInt64) -> u64; + + #[rust_name = "quintptr_from_usize"] + fn quintptrFromUsize(value: usize) -> QUIntPtr; + #[rust_name = "quintptr_into_usize"] + fn quintptrIntoUsize(value: QUIntPtr) -> usize; + + #[rust_name = "qsizetype_from_isize"] + fn qsizetypeFromIsize(value: isize) -> QSizeType; + #[rust_name = "qsizetype_into_isize"] + fn qsizetypeIntoIsize(value: QSizeType) -> isize; + } +} + +#[repr(C)] +pub struct QInt64 { + _space: MaybeUninit, +} + +impl From for QInt64 { + fn from(value: i64) -> Self { + ffi::qint64_from_i64(value) + } +} + +impl From for i64 { + fn from(value: QInt64) -> Self { + ffi::qint64_into_i64(value) + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QInt64 { + type Id = type_id!("qint64"); + type Kind = cxx::kind::Trivial; +} + +#[repr(C)] +pub struct QIntPtr { + _space: MaybeUninit, +} + +impl From for QIntPtr { + fn from(value: isize) -> Self { + ffi::qintptr_from_isize(value) + } +} + +impl From for isize { + fn from(value: QIntPtr) -> Self { + ffi::qintptr_into_isize(value) + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QIntPtr { + type Id = type_id!("qintptr"); + type Kind = cxx::kind::Trivial; +} + +#[repr(C)] +pub struct QUInt64 { + _space: MaybeUninit, +} + +impl From for QUInt64 { + fn from(value: u64) -> Self { + ffi::quint64_from_u64(value) + } +} + +impl From for u64 { + fn from(value: QUInt64) -> Self { + ffi::quint64_into_u64(value) + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QUInt64 { + type Id = type_id!("quint64"); + type Kind = cxx::kind::Trivial; +} + +#[repr(C)] +pub struct QUIntPtr { + _space: MaybeUninit, +} + +impl From for QUIntPtr { + fn from(value: usize) -> Self { + ffi::quintptr_from_usize(value) + } +} + +impl From for usize { + fn from(value: QUIntPtr) -> Self { + ffi::quintptr_into_usize(value) + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QUIntPtr { + type Id = type_id!("quintptr"); + type Kind = cxx::kind::Trivial; +} + +#[repr(C)] +pub struct QSizeType { + _space: MaybeUninit, +} + +impl From for QSizeType { + fn from(value: isize) -> Self { + ffi::qsizetype_from_isize(value) + } +} + +impl From for isize { + fn from(value: QSizeType) -> Self { + ffi::qsizetype_into_isize(value) + } +} + +// Safety: +// +// Static checks on the C++ side to ensure the size is the same. +unsafe impl ExternType for QSizeType { + type Id = type_id!("qsizetype"); + type Kind = cxx::kind::Trivial; +}