Skip to content

Commit fad2915

Browse files
committed
cxx-qt-lib: add binding for QVariant::typeName()
1 parent 2ec40ea commit fad2915

3 files changed

Lines changed: 33 additions & 0 deletions

File tree

crates/cxx-qt-lib/include/core/qvariant.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ qvariantValueOrDefault(const QVariant& variant) noexcept
8585
return variant.value<T>();
8686
}
8787

88+
::rust::Slice<const ::std::uint8_t>
89+
qvariantTypeName(const QVariant& variant) noexcept;
90+
8891
// Need to use a macro here as we can't template because the types
8992
// are always QVariant and bool. So then CXX can't decide which to use.
9093
#define CXX_QT_QVARIANT_CAN_CONVERT(name) \

crates/cxx-qt-lib/src/core/qvariant/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ mod ffi {
5858
#[rust_name = "qvariant_to_debug_qstring"]
5959
fn toDebugQString(variant: &QVariant) -> QString;
6060
}
61+
62+
#[namespace = "rust::cxxqtlib1::qvariant"]
63+
unsafe extern "C++" {
64+
#[doc(hidden)]
65+
#[rust_name = "qvariant_type_name"]
66+
fn qvariantTypeName(variant: &QVariant) -> &[u8];
67+
}
6168
}
6269

6370
/// The `QVariant` class acts like a union for the most common Qt data types.
@@ -119,6 +126,16 @@ impl QVariant {
119126
self.user_type().into()
120127
}
121128

129+
/// Returns the name of the type stored in the variant.
130+
///
131+
/// The returned string describes the C++ datatype used to store the data.
132+
/// An invalid variant returns an empty string.
133+
pub fn type_name(&self) -> &str {
134+
// The slice is empty when the variant has no type name.
135+
let slice = ffi::qvariant_type_name(self);
136+
std::str::from_utf8(slice).expect("QVariant type name is not valid UTF-8")
137+
}
138+
122139
/// Returns the stored value converted to the template type `T`, or `None` if the type cannot be converted to `T`.
123140
///
124141
/// Note that this first calls [`can_convert`](QVariantValue::can_convert).

crates/cxx-qt-lib/src/core/qvariant/qvariant.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#include <cxx-qt-lib/assertion_utils.h>
1313

14+
#include <cstring>
15+
1416
// The layout has changed between Qt 5 and Qt 6
1517
//
1618
// Qt6 QVariant has one member, which contains three pointers and a union
@@ -56,6 +58,17 @@ namespace rust {
5658
namespace cxxqtlib1 {
5759
namespace qvariant {
5860

61+
::rust::Slice<const ::std::uint8_t>
62+
qvariantTypeName(const QVariant& variant) noexcept
63+
{
64+
if (const char* name = variant.typeName()) {
65+
const ::std::size_t len = ::std::strlen(name);
66+
return ::rust::Slice{ reinterpret_cast<const ::std::uint8_t*>(name), len };
67+
}
68+
69+
return {};
70+
}
71+
5972
CXX_QT_QVARIANT_CAN_CONVERT_IMPL(bool, Bool)
6073
CXX_QT_QVARIANT_CAN_CONVERT_IMPL(float, F32)
6174
CXX_QT_QVARIANT_CAN_CONVERT_IMPL(double, F64)

0 commit comments

Comments
 (0)