@@ -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).
@@ -277,3 +294,37 @@ unsafe impl ExternType for QVariant {
277294 type Id = type_id ! ( "QVariant" ) ;
278295 type Kind = cxx:: kind:: Trivial ;
279296}
297+
298+ #[ cfg( test) ]
299+ mod tests {
300+ use super :: * ;
301+ use crate :: { QList , QString } ;
302+
303+ #[ test]
304+ fn test_type_name ( ) {
305+ let variant = QVariant :: from ( & true ) ;
306+ assert_eq ! ( variant. type_name( ) , "bool" ) ;
307+
308+ let variant = QVariant :: from ( & 123_i32 ) ;
309+ assert_eq ! ( variant. type_name( ) , "int" ) ;
310+
311+ let variant = QVariant :: from ( & 0.25f32 ) ;
312+ assert_eq ! ( variant. type_name( ) , "float" ) ;
313+
314+ let variant = QVariant :: from ( & 0.75f64 ) ;
315+ assert_eq ! ( variant. type_name( ) , "double" ) ;
316+
317+ let variant = QVariant :: from ( & QList :: < i32 > :: from_iter ( & [ 1 , 2 , 3 ] ) ) ;
318+ assert_eq ! ( variant. type_name( ) , "QList<int>" ) ;
319+
320+ let variant = QVariant :: from ( & QString :: from ( "ABC" ) ) ;
321+ assert_eq ! ( variant. type_name( ) , "QString" ) ;
322+ }
323+
324+ #[ test]
325+ fn qvariant_type_name_invalid ( ) {
326+ let variant = QVariant :: default ( ) ;
327+ assert ! ( !variant. is_valid( ) ) ;
328+ assert_eq ! ( variant. type_name( ) , "" ) ;
329+ }
330+ }
0 commit comments