Deprecate use of QVariant: too complex

master
Jos van den Oever 2017-08-12 19:21:35 +02:00
parent d66e16f764
commit 30a4076b2f
13 changed files with 314 additions and 128 deletions

View File

@ -4,7 +4,7 @@ add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust/src/testinterface.rs"
"${CMAKE_CURRENT_SOURCE_DIR}/rust/src/testimplementation.rs"
"${CMAKE_CURRENT_SOURCE_DIR}/rust/src/types.rs"
COMMAND ${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator "${CMAKE_CURRENT_SOURCE_DIR}/bindings.json"
COMMAND ${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator --overwrite-implementation "${CMAKE_CURRENT_SOURCE_DIR}/bindings.json"
DEPENDS rust_qt_binding_generator bindings.json
)

View File

@ -20,10 +20,6 @@
"name": "active",
"type": "bool",
"write": true
}, {
"name": "misc",
"type": "QVariant",
"write": true
}, {
"name": "icon",
"type": "QByteArray",

View File

@ -1,5 +1,6 @@
#![allow(unused_imports)]
use libc::c_int;
use libc::c_uint;
use types::*;
use testinterface::*;
@ -8,7 +9,6 @@ pub struct Person {
user_name: String,
age: c_int,
active: bool,
misc: Variant,
icon: Vec<u8>,
}
@ -19,7 +19,6 @@ impl PersonTrait for Person {
user_name: String::new(),
age: 0,
active: true,
misc: Variant::None,
icon: Vec::new(),
}
}
@ -43,13 +42,6 @@ impl PersonTrait for Person {
self.active = value;
self.emit.active_changed();
}
fn get_misc(&self) -> Variant {
self.misc.clone()
}
fn set_misc(&mut self, value: Variant) {
self.misc = value;
self.emit.misc_changed();
}
fn get_icon(&self) -> Vec<u8> {
self.icon.clone()
}

View File

@ -2,7 +2,7 @@
#![allow(unknown_lints)]
#![allow(mutex_atomic, needless_pass_by_value)]
#![allow(unused_imports)]
use libc::{c_int, c_void};
use libc::{c_int, c_uint, c_void};
use types::*;
use std::sync::{Arc, Mutex};
use std::ptr::null;
@ -17,7 +17,6 @@ pub struct PersonEmitter {
user_name_changed: fn(*const PersonQObject),
age_changed: fn(*const PersonQObject),
active_changed: fn(*const PersonQObject),
misc_changed: fn(*const PersonQObject),
icon_changed: fn(*const PersonQObject),
}
@ -45,12 +44,6 @@ impl PersonEmitter {
(self.active_changed)(ptr);
}
}
pub fn misc_changed(&self) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.misc_changed)(ptr);
}
}
pub fn icon_changed(&self) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
@ -67,8 +60,6 @@ pub trait PersonTrait {
fn get_age(&self) -> c_int;
fn get_active(&self) -> bool;
fn set_active(&mut self, value: bool);
fn get_misc(&self) -> Variant;
fn set_misc(&mut self, value: Variant);
fn get_icon(&self) -> Vec<u8>;
fn set_icon(&mut self, value: Vec<u8>);
}
@ -78,7 +69,6 @@ pub extern "C" fn person_new(qobject: *const PersonQObject,
user_name_changed: fn(*const PersonQObject),
age_changed: fn(*const PersonQObject),
active_changed: fn(*const PersonQObject),
misc_changed: fn(*const PersonQObject),
icon_changed: fn(*const PersonQObject))
-> *mut Person {
let emit = PersonEmitter {
@ -86,7 +76,6 @@ pub extern "C" fn person_new(qobject: *const PersonQObject,
user_name_changed: user_name_changed,
age_changed: age_changed,
active_changed: active_changed,
misc_changed: misc_changed,
icon_changed: icon_changed,
};
let d = Person::create(emit);
@ -126,19 +115,6 @@ pub unsafe extern "C" fn person_active_set(ptr: *mut Person, v: bool) {
(&mut *ptr).set_active(v);
}
#[no_mangle]
pub unsafe extern "C" fn person_misc_get(ptr: *const Person,
p: *mut c_void,
set: fn(*mut c_void, QVariant)) {
let data = (&*ptr).get_misc();
set(p, QVariant::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn person_misc_set(ptr: *mut Person, v: QVariant) {
(&mut *ptr).set_misc(v.convert());
}
#[no_mangle]
pub unsafe extern "C" fn person_icon_get(ptr: *const Person,
p: *mut c_void,

View File

@ -110,15 +110,13 @@ void set_qvariant(QVariant* v, qvariant_t* val) {
}
extern "C" {
PersonInterface* person_new(Person*, void (*)(Person*), void (*)(Person*), void (*)(Person*), void (*)(Person*), void (*)(Person*));
PersonInterface* person_new(Person*, void (*)(Person*), void (*)(Person*), void (*)(Person*), void (*)(Person*));
void person_free(PersonInterface*);
void person_user_name_get(PersonInterface*, QString*, qstring_set);
void person_user_name_set(void*, qstring_t);
int person_age_get(PersonInterface*);
bool person_active_get(PersonInterface*);
void person_active_set(void*, bool);
void person_misc_get(PersonInterface*, QVariant*, qvariant_set);
void person_misc_set(void*, qvariant_t);
void person_icon_get(PersonInterface*, QByteArray*, qbytearray_set);
void person_icon_set(void*, qbytearray_t);
DirectoryInterface* directory_new(Directory*, void (*)(Directory*),
@ -136,7 +134,6 @@ Person::Person(QObject *parent):
[](Person* o) { emit o->userNameChanged(); },
[](Person* o) { emit o->ageChanged(); },
[](Person* o) { emit o->activeChanged(); },
[](Person* o) { emit o->miscChanged(); },
[](Person* o) { emit o->iconChanged(); })) {}
Person::~Person() {
@ -162,15 +159,6 @@ bool Person::active() const
void Person::setActive(bool v) {
person_active_set(d, v);
}
QVariant Person::misc() const
{
QVariant v;
person_misc_get(d, &v, set_qvariant);
return v;
}
void Person::setMisc(const QVariant& v) {
variant(v, d, person_misc_set);
}
QByteArray Person::icon() const
{
QByteArray v;

View File

@ -14,7 +14,6 @@ class Person : public QObject
Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged FINAL)
Q_PROPERTY(int age READ age NOTIFY ageChanged FINAL)
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged FINAL)
Q_PROPERTY(QVariant misc READ misc WRITE setMisc NOTIFY miscChanged FINAL)
Q_PROPERTY(QByteArray icon READ icon WRITE setIcon NOTIFY iconChanged FINAL)
public:
explicit Person(QObject *parent = nullptr);
@ -24,21 +23,17 @@ public:
int age() const;
bool active() const;
void setActive(bool v);
QVariant misc() const;
void setMisc(const QVariant& v);
QByteArray icon() const;
void setIcon(const QByteArray& v);
signals:
void userNameChanged();
void ageChanged();
void activeChanged();
void miscChanged();
void iconChanged();
private:
QString m_userName;
int m_age;
bool m_active;
QVariant m_misc;
QByteArray m_icon;
};

View File

@ -19,6 +19,7 @@ enum ObjectType {
enum class BindingType {
Bool,
Int,
UInt,
QString,
QByteArray,
QVariant
@ -57,6 +58,13 @@ const QMap<BindingType, BindingTypeProperties>& bindingTypeProperties() {
.rustType = "c_int",
.rustTypeInit = "0"
});
f.insert(BindingType::UInt, {
.name = "uint",
.cppSetType = "uint",
.cSetType = "uint",
.rustType = "c_uint",
.rustTypeInit = "0"
});
f.insert(BindingType::QString, {
.name = "QString",
.cppSetType = "const QString&",
@ -71,13 +79,6 @@ const QMap<BindingType, BindingTypeProperties>& bindingTypeProperties() {
.rustType = "Vec<u8>",
.rustTypeInit = "Vec::new()"
});
f.insert(BindingType::QVariant, {
.name = "QVariant",
.cppSetType = "const QVariant&",
.cSetType = "qvariant_t",
.rustType = "Variant",
.rustTypeInit = "Variant::None"
});
p = f;
}
return p;
@ -836,7 +837,7 @@ void writeRustInterface(const Configuration& conf) {
#![allow(unknown_lints)]
#![allow(mutex_atomic, needless_pass_by_value)]
#![allow(unused_imports)]
use libc::{c_int, c_void};
use libc::{c_int, c_uint, c_void};
use types::*;
use std::sync::{Arc, Mutex};
use std::ptr::null;
@ -915,6 +916,7 @@ void writeRustImplementation(const Configuration& conf) {
QTextStream r(&w.buffer);
r << QString(R"(#![allow(unused_imports)]
use libc::c_int;
use libc::c_uint;
use types::*;
use %1::*;

View File

@ -1,28 +1,65 @@
#![allow(unused_imports)]
use libc::c_int;
use libc::c_uint;
use types::*;
use interface::*;
pub struct Object {
emit: ObjectEmitter,
value: Variant,
boolean: bool,
integer: c_int,
uinteger: c_uint,
string: String,
bytearray: Vec<u8>,
}
impl ObjectTrait for Object {
fn create(emit: ObjectEmitter) -> Object {
Object {
emit: emit,
value: Variant::None,
boolean: true,
integer: 0,
uinteger: 0,
string: String::new(),
bytearray: Vec::new(),
}
}
fn emit(&self) -> &ObjectEmitter {
&self.emit
}
fn get_value(&self) -> Variant {
self.value.clone()
fn get_boolean(&self) -> bool {
self.boolean
}
fn set_value(&mut self, value: Variant) {
self.value = value;
self.emit.value_changed();
fn set_boolean(&mut self, value: bool) {
self.boolean = value;
self.emit.boolean_changed();
}
fn get_integer(&self) -> c_int {
self.integer
}
fn set_integer(&mut self, value: c_int) {
self.integer = value;
self.emit.integer_changed();
}
fn get_uinteger(&self) -> c_uint {
self.uinteger
}
fn set_uinteger(&mut self, value: c_uint) {
self.uinteger = value;
self.emit.uinteger_changed();
}
fn get_string(&self) -> String {
self.string.clone()
}
fn set_string(&mut self, value: String) {
self.string = value;
self.emit.string_changed();
}
fn get_bytearray(&self) -> Vec<u8> {
self.bytearray.clone()
}
fn set_bytearray(&mut self, value: Vec<u8>) {
self.bytearray = value;
self.emit.bytearray_changed();
}
}

View File

@ -2,7 +2,7 @@
#![allow(unknown_lints)]
#![allow(mutex_atomic, needless_pass_by_value)]
#![allow(unused_imports)]
use libc::{c_int, c_void};
use libc::{c_int, c_uint, c_void};
use types::*;
use std::sync::{Arc, Mutex};
use std::ptr::null;
@ -14,7 +14,11 @@ pub struct ObjectQObject {}
#[derive (Clone)]
pub struct ObjectEmitter {
qobject: Arc<Mutex<*const ObjectQObject>>,
value_changed: fn(*const ObjectQObject),
boolean_changed: fn(*const ObjectQObject),
integer_changed: fn(*const ObjectQObject),
uinteger_changed: fn(*const ObjectQObject),
string_changed: fn(*const ObjectQObject),
bytearray_changed: fn(*const ObjectQObject),
}
unsafe impl Send for ObjectEmitter {}
@ -23,10 +27,34 @@ impl ObjectEmitter {
fn clear(&self) {
*self.qobject.lock().unwrap() = null();
}
pub fn value_changed(&self) {
pub fn boolean_changed(&self) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.value_changed)(ptr);
(self.boolean_changed)(ptr);
}
}
pub fn integer_changed(&self) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.integer_changed)(ptr);
}
}
pub fn uinteger_changed(&self) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.uinteger_changed)(ptr);
}
}
pub fn string_changed(&self) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.string_changed)(ptr);
}
}
pub fn bytearray_changed(&self) {
let ptr = *self.qobject.lock().unwrap();
if !ptr.is_null() {
(self.bytearray_changed)(ptr);
}
}
}
@ -34,17 +62,33 @@ impl ObjectEmitter {
pub trait ObjectTrait {
fn create(emit: ObjectEmitter) -> Self;
fn emit(&self) -> &ObjectEmitter;
fn get_value(&self) -> Variant;
fn set_value(&mut self, value: Variant);
fn get_boolean(&self) -> bool;
fn set_boolean(&mut self, value: bool);
fn get_integer(&self) -> c_int;
fn set_integer(&mut self, value: c_int);
fn get_uinteger(&self) -> c_uint;
fn set_uinteger(&mut self, value: c_uint);
fn get_string(&self) -> String;
fn set_string(&mut self, value: String);
fn get_bytearray(&self) -> Vec<u8>;
fn set_bytearray(&mut self, value: Vec<u8>);
}
#[no_mangle]
pub extern "C" fn object_new(qobject: *const ObjectQObject,
value_changed: fn(*const ObjectQObject))
boolean_changed: fn(*const ObjectQObject),
integer_changed: fn(*const ObjectQObject),
uinteger_changed: fn(*const ObjectQObject),
string_changed: fn(*const ObjectQObject),
bytearray_changed: fn(*const ObjectQObject))
-> *mut Object {
let emit = ObjectEmitter {
qobject: Arc::new(Mutex::new(qobject)),
value_changed: value_changed,
boolean_changed: boolean_changed,
integer_changed: integer_changed,
uinteger_changed: uinteger_changed,
string_changed: string_changed,
bytearray_changed: bytearray_changed,
};
let d = Object::create(emit);
Box::into_raw(Box::new(d))
@ -56,14 +100,57 @@ pub unsafe extern "C" fn object_free(ptr: *mut Object) {
}
#[no_mangle]
pub unsafe extern "C" fn object_value_get(ptr: *const Object,
p: *mut c_void,
set: fn(*mut c_void, QVariant)) {
let data = (&*ptr).get_value();
set(p, QVariant::from(&data));
pub unsafe extern "C" fn object_boolean_get(ptr: *const Object) -> bool {
(&*ptr).get_boolean()
}
#[no_mangle]
pub unsafe extern "C" fn object_value_set(ptr: *mut Object, v: QVariant) {
(&mut *ptr).set_value(v.convert());
pub unsafe extern "C" fn object_boolean_set(ptr: *mut Object, v: bool) {
(&mut *ptr).set_boolean(v);
}
#[no_mangle]
pub unsafe extern "C" fn object_integer_get(ptr: *const Object) -> c_int {
(&*ptr).get_integer()
}
#[no_mangle]
pub unsafe extern "C" fn object_integer_set(ptr: *mut Object, v: c_int) {
(&mut *ptr).set_integer(v);
}
#[no_mangle]
pub unsafe extern "C" fn object_uinteger_get(ptr: *const Object) -> c_uint {
(&*ptr).get_uinteger()
}
#[no_mangle]
pub unsafe extern "C" fn object_uinteger_set(ptr: *mut Object, v: c_uint) {
(&mut *ptr).set_uinteger(v);
}
#[no_mangle]
pub unsafe extern "C" fn object_string_get(ptr: *const Object,
p: *mut c_void,
set: fn(*mut c_void, QString)) {
let data = (&*ptr).get_string();
set(p, QString::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn object_string_set(ptr: *mut Object, v: QStringIn) {
(&mut *ptr).set_string(v.convert());
}
#[no_mangle]
pub unsafe extern "C" fn object_bytearray_get(ptr: *const Object,
p: *mut c_void,
set: fn(*mut c_void, QByteArray)) {
let data = (&*ptr).get_bytearray();
set(p, QByteArray::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn object_bytearray_set(ptr: *mut Object, v: QByteArray) {
(&mut *ptr).set_bytearray(v.convert());
}

View File

@ -7,46 +7,81 @@ class TestRustObjectTypes : public QObject
{
Q_OBJECT
private slots:
void testSetter();
void testSetter_data();
// no support for QVariant: it's too hard to implement all of it
// void testSetter();
// void testSetter_data();
void testBool();
void testInteger();
void testUinteger();
void testString();
void testByteArray();
};
void TestRustObjectTypes::testSetter()
template <typename V, typename Set, typename Get, typename Changed>
void testSetter(V v, Set set, Get get, Changed changed)
{
// GIVEN
QFETCH(QVariant, value);
Object object;
QSignalSpy spy(&object, &Object::valueChanged);
QSignalSpy spy(&object, changed);
// WHEN
object.setValue(value);
(object.*set)((V)v);
// THEN
QVERIFY(spy.isValid());
QCOMPARE(spy.count(), 1);
auto resultType = object.value().type();
QCOMPARE(resultType, value.type());
QCOMPARE(object.value(), value);
QCOMPARE((V)(object.*get)(), (V)v);
}
void TestRustObjectTypes::testSetter_data()
void TestRustObjectTypes::testBool()
{
QTest::addColumn<QVariant>("value");
QTest::newRow("invalid") << QVariant();
QTest::newRow("true") << QVariant(true);
QTest::newRow("false") << QVariant(false);
QTest::newRow("0") << QVariant((int)0);
QTest::newRow("1") << QVariant((int)1);
int min_int = std::numeric_limits<int>::min();
QTest::newRow("min_int") << QVariant(min_int);
int max_int = std::numeric_limits<int>::max();
QTest::newRow("max_int") << QVariant(max_int);
QTest::newRow("QString()") << QVariant(QString());
QTest::newRow("QString(Konqi)") << QVariant("Konqi");
QTest::newRow("QString($€𐐷𤭢)") << QVariant("$€𐐷𤭢");
QTest::newRow("QByteArray()") << QVariant(QByteArray());
testSetter(true, &Object::setBoolean,
&Object::boolean, &Object::booleanChanged);
testSetter(false, &Object::setBoolean,
&Object::boolean, &Object::booleanChanged);
}
void TestRustObjectTypes::testInteger()
{
testSetter(0, &Object::setInteger,
&Object::integer, &Object::integerChanged);
testSetter(1, &Object::setInteger,
&Object::integer, &Object::integerChanged);
testSetter(std::numeric_limits<int>::min(), &Object::setInteger,
&Object::integer, &Object::integerChanged);
testSetter(std::numeric_limits<int>::max(), &Object::setInteger,
&Object::integer, &Object::integerChanged);
}
void TestRustObjectTypes::testUinteger()
{
testSetter(0, &Object::setUinteger,
&Object::uinteger, &Object::uintegerChanged);
testSetter(1, &Object::setUinteger,
&Object::uinteger, &Object::uintegerChanged);
testSetter(std::numeric_limits<uint>::min(), &Object::setUinteger,
&Object::uinteger, &Object::uintegerChanged);
testSetter(std::numeric_limits<uint>::max(), &Object::setUinteger,
&Object::uinteger, &Object::uintegerChanged);
}
void TestRustObjectTypes::testString()
{
testSetter(QString(), &Object::setString,
&Object::string, &Object::stringChanged);
testSetter(QString("Konqi"), &Object::setString,
&Object::string, &Object::stringChanged);
testSetter(QString("$𐐷𤭢"), &Object::setString,
&Object::string, &Object::stringChanged);
}
void TestRustObjectTypes::testByteArray()
{
testSetter(QByteArray(), &Object::setBytearray,
&Object::bytearray, &Object::bytearrayChanged);
const char data[10] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9};
QTest::newRow("QByteArray(data)") << QVariant(QByteArray(data, 10));
testSetter(QByteArray(data, 10), &Object::setBytearray,
&Object::bytearray, &Object::bytearrayChanged);
}
QTEST_MAIN(TestRustObjectTypes)

View File

@ -10,8 +10,24 @@
"name": "Object",
"type": "Object",
"properties": [{
"name": "value",
"type": "QVariant",
"name": "boolean",
"type": "bool",
"write": true
}, {
"name": "integer",
"type": "int",
"write": true
}, {
"name": "uinteger",
"type": "uint",
"write": true
}, {
"name": "string",
"type": "QString",
"write": true
}, {
"name": "bytearray",
"type": "QByteArray",
"write": true
}]
}]

View File

@ -110,25 +110,67 @@ void set_qvariant(QVariant* v, qvariant_t* val) {
}
extern "C" {
ObjectInterface* object_new(Object*, void (*)(Object*));
ObjectInterface* object_new(Object*, void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*));
void object_free(ObjectInterface*);
void object_value_get(ObjectInterface*, QVariant*, qvariant_set);
void object_value_set(void*, qvariant_t);
bool object_boolean_get(ObjectInterface*);
void object_boolean_set(void*, bool);
int object_integer_get(ObjectInterface*);
void object_integer_set(void*, int);
uint object_uinteger_get(ObjectInterface*);
void object_uinteger_set(void*, uint);
void object_string_get(ObjectInterface*, QString*, qstring_set);
void object_string_set(void*, qstring_t);
void object_bytearray_get(ObjectInterface*, QByteArray*, qbytearray_set);
void object_bytearray_set(void*, qbytearray_t);
};
Object::Object(QObject *parent):
QObject(parent),
d(object_new(this,
[](Object* o) { emit o->valueChanged(); })) {}
[](Object* o) { emit o->booleanChanged(); },
[](Object* o) { emit o->integerChanged(); },
[](Object* o) { emit o->uintegerChanged(); },
[](Object* o) { emit o->stringChanged(); },
[](Object* o) { emit o->bytearrayChanged(); })) {}
Object::~Object() {
object_free(d);
}
QVariant Object::value() const
bool Object::boolean() const
{
QVariant v;
object_value_get(d, &v, set_qvariant);
return object_boolean_get(d);
}
void Object::setBoolean(bool v) {
object_boolean_set(d, v);
}
int Object::integer() const
{
return object_integer_get(d);
}
void Object::setInteger(int v) {
object_integer_set(d, v);
}
uint Object::uinteger() const
{
return object_uinteger_get(d);
}
void Object::setUinteger(uint v) {
object_uinteger_set(d, v);
}
QString Object::string() const
{
QString v;
object_string_get(d, &v, set_qstring);
return v;
}
void Object::setValue(const QVariant& v) {
variant(v, d, object_value_set);
void Object::setString(const QString& v) {
object_string_set(d, v);
}
QByteArray Object::bytearray() const
{
QByteArray v;
object_bytearray_get(d, &v, set_qbytearray);
return v;
}
void Object::setBytearray(const QByteArray& v) {
object_bytearray_set(d, v);
}

View File

@ -11,15 +11,35 @@ class Object : public QObject
{
Q_OBJECT
ObjectInterface * const d;
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged FINAL)
Q_PROPERTY(bool boolean READ boolean WRITE setBoolean NOTIFY booleanChanged FINAL)
Q_PROPERTY(int integer READ integer WRITE setInteger NOTIFY integerChanged FINAL)
Q_PROPERTY(uint uinteger READ uinteger WRITE setUinteger NOTIFY uintegerChanged FINAL)
Q_PROPERTY(QString string READ string WRITE setString NOTIFY stringChanged FINAL)
Q_PROPERTY(QByteArray bytearray READ bytearray WRITE setBytearray NOTIFY bytearrayChanged FINAL)
public:
explicit Object(QObject *parent = nullptr);
~Object();
QVariant value() const;
void setValue(const QVariant& v);
bool boolean() const;
void setBoolean(bool v);
int integer() const;
void setInteger(int v);
uint uinteger() const;
void setUinteger(uint v);
QString string() const;
void setString(const QString& v);
QByteArray bytearray() const;
void setBytearray(const QByteArray& v);
signals:
void valueChanged();
void booleanChanged();
void integerChanged();
void uintegerChanged();
void stringChanged();
void bytearrayChanged();
private:
QVariant m_value;
bool m_boolean;
int m_integer;
uint m_uinteger;
QString m_string;
QByteArray m_bytearray;
};
#endif // TEST_OBJECT_TYPES_RUST_H