Add a test

master
Jos van den Oever 2017-08-11 17:24:24 +02:00
parent bced2e9ba3
commit 25d65e1b9e
15 changed files with 847 additions and 23 deletions

View File

@ -15,28 +15,13 @@ include(KDECMakeSettings)
include(KDECompilerSettings)
include(FeatureSummary)
#add_custom_target(rust
# OUTPUT "${CMAKE_SOURCE_DIR}/target/debug/librust.a"
# COMMAND cargo build
# COMMAND cargo build --release
# DEPENDS
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/Rust)
ExternalProject_Add(
rust
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND cargo build
COMMAND cargo build --release
BINARY_DIR "${CMAKE_SOURCE_DIR}/common-rust"
INSTALL_COMMAND ""
LOG_BUILD ON)
# Find Qt modules
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
Core # QCommandLineParser, QStringLiteral
Quick
Test
Widgets # QApplication
)
@ -51,12 +36,38 @@ feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAG
add_subdirectory(rust_qt_binding_generator)
string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER)
if(CMAKE_BUILD_TYPE_UPPER STREQUAL DEBUG)
set(RUST_TARGET_DIR target/debug/)
set(RUST_BUILD_FLAG)
else()
set(RUST_TARGET_DIR target/release/)
set(RUST_BUILD_FLAG --release)
endif()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/common-rust/src/testinterface.rs"
COMMAND ${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator "${CMAKE_CURRENT_SOURCE_DIR}/bindings.json"
DEPENDS rust_qt_binding_generator bindings.json
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/common-rust/${RUST_TARGET_DIR}/librust.a"
COMMAND cargo build ${RUST_BUILD_FLAG}
DEPENDS common-rust/src/lib.rs
common-rust/src/testimplementation.rs
common-rust/src/testinterface.rs
common-rust/src/implementation.rs
common-rust/src/interface.rs
common-rust/src/types.rs
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/common-rust"
)
add_custom_target(rust_target DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/common-rust/${RUST_TARGET_DIR}/librust.a")
set(RMail_SRCS src/main.cpp src/RMailObject.cpp src/tmp.cpp)
add_executable(RMail ${RMail_SRCS})
add_dependencies(RMail rust)
add_dependencies(RMail rust_target)
target_link_libraries(RMail
Qt5::Quick
@ -64,8 +75,7 @@ target_link_libraries(RMail
KF5::CoreAddons
KF5::I18n
KF5::WidgetsAddons
debug "${CMAKE_SOURCE_DIR}/common-rust/target/debug/librust.a"
optimized "${CMAKE_SOURCE_DIR}/common-rust/target/release/librust.a"
"${CMAKE_CURRENT_SOURCE_DIR}/common-rust/${RUST_TARGET_DIR}/librust.a"
)
set_target_properties(RMail PROPERTIES
@ -74,3 +84,6 @@ set_target_properties(RMail PROPERTIES
)
install(TARGETS RMail ${INSTALL_TARGETS_DEFAULT_ARGS})
add_subdirectory(tests)

2
dev
View File

@ -1,3 +1,3 @@
#!/usr/bin/bash
rm -rf __nix_qt5__/
nix-shell -p qtcreator cmake ninja gcc rustc cargo qt5.full extra-cmake-modules kdeFrameworks.kwidgetsaddons kdeFrameworks.kcoreaddons kdeFrameworks.ki18n appstream
nix-shell -p qtcreator cmake ninja gcc rustc cargo qt5.full extra-cmake-modules kdeFrameworks.kwidgetsaddons kdeFrameworks.kcoreaddons kdeFrameworks.ki18n appstream cmakeCurses

View File

@ -100,6 +100,7 @@ parseConfiguration(const QString& path) {
const QJsonObject o = doc.object();
Configuration c;
c.cppFile = QFileInfo(base, o.value("cppFile").toString());
QDir(c.cppFile.dir()).mkpath(".");
c.hFile = QFileInfo(c.cppFile.dir(), c.cppFile.completeBaseName() + ".h");
for (const QJsonValue& val: o.value("objects").toArray()) {
c.objects.append(parseObject(val.toObject()));

View File

@ -62,7 +62,7 @@ int main (int argc, char *argv[])
view.show();
engine.rootContext()->setContextProperty("fsModel", &model);
engine.load(QUrl(QStringLiteral("test.qml")));
engine.load(QUrl(QStringLiteral("../test.qml")));
return app.exec();
/*

275
src/tmp.cpp Normal file
View File

@ -0,0 +1,275 @@
/* generated by rust_qt_binding_generator */
#include "tmp.h"
#include <QModelIndex>
namespace {
struct qbytearray_t {
private:
const char* data;
int len;
public:
qbytearray_t(const QByteArray& v):
data(v.data()),
len(v.size()) {
}
operator QByteArray() const {
return QByteArray(data, len);
}
};
struct qstring_t {
private:
const void* data;
int len;
public:
qstring_t(const QString& v):
data(static_cast<const void*>(v.utf16())),
len(v.size()) {
}
operator QString() const {
return QString::fromUtf8(static_cast<const char*>(data), len);
}
};
struct qmodelindex_t {
int row;
int column;
uint64_t id;
qmodelindex_t(const QModelIndex& m):
row(m.row()), column(m.column()), id(m.internalId()) {}
};
struct qvariant_t {
unsigned int type;
int value;
const char* data;
};
QVariant variant(const qvariant_t& v) {
switch (v.type) {
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value);
default:;
}
return QVariant();
}
void variant(const QByteArray& v, void* d, void (*set)(void*, qvariant_t)) {
set(d, {
.type = QVariant::ByteArray,
.value = v.length(),
.data = v.data()
});
}
void variant(const QString& v, void* d, void (*set)(void*, qvariant_t)) {
set(d, {
.type = QVariant::String,
.value = v.size(),
.data = static_cast<const char*>(static_cast<const void*>(v.utf16()))
});
}
void variant(const QVariant& v, void* d, void (*set)(void*, qvariant_t)) {
switch (v.type()) {
case QVariant::Bool:
set(d, {
.type = QVariant::Bool,
.value = v.toBool(),
.data = 0
});
break;
case QVariant::Int:
set(d, {
.type = QVariant::Int,
.value = v.toInt(),
.data = 0
});
break;
case QVariant::ByteArray:
variant(v.toByteArray(), d, set);
break;
case QVariant::String:
variant(v.toString(), d, set);
break;
default:
set(d, {
.type = QVariant::Invalid,
.value = 0,
.data = 0
});
}
}
}
typedef void (*qstring_set)(QString*, qstring_t*);
void set_qstring(QString* v, qstring_t* val) {
*v = *val;
}
typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*);
void set_qbytearray(QByteArray* v, qbytearray_t* val) {
*v = *val;
}
typedef void (*qvariant_set)(QVariant*, qvariant_t*);
void set_qvariant(QVariant* v, qvariant_t* val) {
*v = variant(*val);
}
extern "C" {
PersonInterface* person_new(Person*, void (*)(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*),
void (*)(Directory*, int, int),
void (*)(Directory*),
void (*)(Directory*, int, int),
void (*)(Directory*));
void directory_free(DirectoryInterface*);
void directory_path_get(DirectoryInterface*, QString*, qstring_set);
void directory_path_set(void*, qstring_t);
};
Person::Person(QObject *parent):
QObject(parent),
d(person_new(this,
[](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() {
person_free(d);
}
QString Person::userName() const
{
QString v;
person_user_name_get(d, &v, set_qstring);
return v;
}
void Person::setUserName(const QString& v) {
person_user_name_set(d, v);
}
int Person::age() const
{
return person_age_get(d);
}
bool Person::active() const
{
return person_active_get(d);
}
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;
person_icon_get(d, &v, set_qbytearray);
return v;
}
void Person::setIcon(const QByteArray& v) {
person_icon_set(d, v);
}
Directory::Directory(QObject *parent):
QAbstractItemModel(parent),
d(directory_new(this,
[](Directory* o) { emit o->pathChanged(); },
[](Directory* o, int first, int last) {
emit o->beginInsertRows(QModelIndex(), first, last);
},
[](Directory* o) {
emit o->endInsertRows();
},
[](Directory* o, int first, int last) {
emit o->beginRemoveRows(QModelIndex(), first, last);
},
[](Directory* o) {
emit o->endRemoveRows();
}
)) {}
Directory::~Directory() {
directory_free(d);
}
QString Directory::path() const
{
QString v;
directory_path_get(d, &v, set_qstring);
return v;
}
void Directory::setPath(const QString& v) {
directory_path_set(d, v);
}
enum DirectoryRole {
DirectoryRoleFileIcon = Qt::DecorationRole,
DirectoryRoleFilePath = Qt::UserRole + 1,
DirectoryRoleFileName = Qt::UserRole + 2,
DirectoryRoleFilePermissions = Qt::UserRole + 3,
};
extern "C" {
void directory_data_file_icon(DirectoryInterface*, int, QVariant*, qvariant_set);
void directory_data_file_path(DirectoryInterface*, int, QVariant*, qvariant_set);
void directory_data_file_name(DirectoryInterface*, int, QVariant*, qvariant_set);
void directory_data_file_permissions(DirectoryInterface*, int, QVariant*, qvariant_set);
int directory_row_count(DirectoryInterface*, qmodelindex_t parent);
}
int Directory::columnCount(const QModelIndex &parent) const
{
return (parent.isValid()) ? 0 : 1;
}
int Directory::rowCount(const QModelIndex &parent) const
{
return (parent.isValid()) ? 0 : directory_row_count(d, parent);
}
QModelIndex Directory::index(int row, int column, const QModelIndex &parent) const
{
if (!parent.isValid() && column == 0) {
return createIndex(row, 0, (quintptr)0);
}
return QModelIndex();
}
QModelIndex Directory::parent(const QModelIndex &) const
{
return QModelIndex();
}
QVariant Directory::data(const QModelIndex &index, int role) const
{
QVariant v;
switch ((DirectoryRole)role) {
case DirectoryRoleFileIcon:
directory_data_file_icon(d, index.row(), &v, set_qvariant);
break;
case DirectoryRoleFilePath:
directory_data_file_path(d, index.row(), &v, set_qvariant);
break;
case DirectoryRoleFileName:
directory_data_file_name(d, index.row(), &v, set_qvariant);
break;
case DirectoryRoleFilePermissions:
directory_data_file_permissions(d, index.row(), &v, set_qvariant);
break;
}
return v;
}
QHash<int, QByteArray> Directory::roleNames() const {
QHash<int, QByteArray> names;
names.insert(Qt::DecorationRole, "FileIcon");
names.insert(Qt::UserRole + 1, "FilePath");
names.insert(Qt::UserRole + 2, "FileName");
names.insert(Qt::UserRole + 3, "FilePermissions");
return names;
}

70
src/tmp.h Normal file
View File

@ -0,0 +1,70 @@
/* generated by rust_qt_binding_generator */
#ifndef TMP_H
#define TMP_H
#include <QObject>
#include <QVariant>
#include <QAbstractItemModel>
class PersonInterface;
class Person : public QObject
{
Q_OBJECT
PersonInterface * const d;
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);
~Person();
QString userName() const;
void setUserName(const QString& v);
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;
};
class DirectoryInterface;
class Directory : public QAbstractItemModel
{
Q_OBJECT
DirectoryInterface * const d;
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged FINAL)
public:
explicit Directory(QObject *parent = nullptr);
~Directory();
QString path() const;
void setPath(const QString& v);
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent) const;
QHash<int, QByteArray> roleNames() const;
signals:
void newDataReady();
signals:
void pathChanged();
private:
QString m_path;
};
#endif // TMP_H

33
tests/CMakeLists.txt Normal file
View File

@ -0,0 +1,33 @@
enable_testing()
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/src/interface.rs"
COMMAND "${CMAKE_COMMAND}" -E remove "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/src/implementation.rs"
COMMAND ${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator "${CMAKE_CURRENT_SOURCE_DIR}/test_object.json"
DEPENDS rust_qt_binding_generator test_object.json
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/${RUST_TARGET_DIR}/librust.a"
COMMAND cargo build ${RUST_BUILD_FLAG}
DEPENDS rust_object/src/lib.rs
rust_object/src/implementation.rs
rust_object/src/interface.rs
rust_object/src/types.rs
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/rust_object"
)
add_custom_target(test_rust_object DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/rust_object/${RUST_TARGET_DIR}/librust.a")
add_executable(test_object test_object.cpp test_object_rust.cpp)
add_dependencies(test_object test_rust_object)
target_link_libraries(test_object
Qt5::Core
Qt5::Test
"${CMAKE_CURRENT_SOURCE_DIR}/rust_object/${RUST_TARGET_DIR}/librust.a"
)
add_test(remove_test_object "${CMAKE_COMMAND}" -E remove test_object)
add_test(build_test_object "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target test_object)
set_tests_properties(build_test_object PROPERTIES DEPENDS remove_test_object)
add_test(test_object test_object)
set_tests_properties(test_object PROPERTIES DEPENDS build_test_object)

View File

@ -0,0 +1,10 @@
[package]
name = "rust_object"
version = "1.0.0"
[dependencies]
libc = "*"
[lib]
name = "rust"
crate-type = ["staticlib"]

View File

@ -0,0 +1,27 @@
use libc::c_int;
use types::*;
use interface::*;
pub struct Person {
emit: PersonEmitter,
user_name: String,
}
impl PersonTrait for Person {
fn create(emit: PersonEmitter) -> Person {
Person {
emit: emit,
user_name: String::new(),
}
}
fn emit(&self) -> &PersonEmitter {
&self.emit
}
fn get_user_name(&self) -> String {
self.user_name.clone()
}
fn set_user_name(&mut self, value: String) {
self.user_name = value;
self.emit.user_name_changed();
}
}

View File

@ -0,0 +1,5 @@
extern crate libc;
mod types;
pub mod interface;
mod implementation;

View File

@ -0,0 +1,184 @@
use std::slice;
use libc::{c_int, c_uint, uint8_t, uint16_t};
use std::ptr::null;
use std::marker::PhantomData;
#[repr(C)]
pub struct QString {
data: *const uint8_t,
len: c_int,
}
#[repr(C)]
pub struct QStringIn {
data: *const uint16_t,
len: c_int,
}
impl QStringIn {
pub fn convert(&self) -> String {
let data = unsafe { slice::from_raw_parts(self.data, self.len as usize) };
String::from_utf16_lossy(data)
}
}
impl<'a> From<&'a String> for QString {
fn from(string: &'a String) -> QString {
QString {
len: string.len() as c_int,
data: string.as_ptr(),
}
}
}
#[repr(C)]
pub struct QByteArray {
data: *const uint8_t,
len: c_int,
}
impl QByteArray {
pub fn convert(&self) -> Vec<u8> {
let data = unsafe { slice::from_raw_parts(self.data, self.len as usize) };
Vec::from(data)
}
}
impl<'a> From<&'a Vec<u8>> for QByteArray {
fn from(value: &'a Vec<u8>) -> QByteArray {
QByteArray {
len: value.len() as c_int,
data: value.as_ptr(),
}
}
}
#[derive(Clone)]
pub enum Variant {
None,
Bool(bool),
String(String),
ByteArray(Vec<u8>),
}
impl From<bool> for Variant {
fn from(value: bool) -> Variant {
Variant::Bool(value)
}
}
impl From<String> for Variant {
fn from(value: String) -> Variant {
Variant::String(value)
}
}
/* values from qvariant.h and qmetatype.h */
#[repr(u32)]
#[derive(Clone, Copy)]
enum VariantType {
Invalid = 0,
Bool = 1,
String = 10,
ByteArray = 12,
}
#[repr(C)]
pub struct QVariant<'a> {
type_: c_uint,
len: c_int,
data: *const uint8_t,
phantom: PhantomData<&'a u8>,
}
impl<'a> QVariant<'a> {
pub fn type_(&self) -> u32 {
self.type_ as u32
}
pub fn convert(&self) -> Variant {
// TODO
Variant::None
}
}
impl<'a> From<&'a Variant> for QVariant<'a> {
fn from(variant: &'a Variant) -> QVariant {
match *variant {
Variant::None => {
QVariant {
data: null(),
len: 0,
type_: VariantType::Invalid as c_uint,
phantom: PhantomData,
}
}
Variant::Bool(v) => {
QVariant {
data: null(),
len: v as c_int,
type_: VariantType::Bool as c_uint,
phantom: PhantomData,
}
}
Variant::String(ref v) => {
QVariant {
data: v.as_ptr(),
len: v.len() as c_int,
type_: VariantType::String as c_uint,
phantom: PhantomData,
}
}
Variant::ByteArray(ref v) => {
QVariant {
data: v.as_ptr(),
len: v.len() as c_int,
type_: VariantType::ByteArray as c_uint,
phantom: PhantomData,
}
}
}
}
}
#[repr(C)]
pub struct QModelIndex {
row: c_int,
column: c_int,
internal_id: usize,
}
impl QModelIndex {
pub fn invalid() -> QModelIndex {
QModelIndex {
row: -1,
column: -1,
internal_id: 0,
}
}
pub fn create(row: c_int, column: c_int, id: usize) -> QModelIndex {
QModelIndex {
row: row,
column: column,
internal_id: id,
}
}
pub fn flat(row: c_int, column: c_int) -> QModelIndex {
QModelIndex {
row: row,
column: column,
internal_id: 1,
}
}
pub fn is_valid(&self) -> bool {
self.internal_id != 0 && self.row >= 0 && self.column >= 0
}
pub fn row(&self) -> c_int {
self.row
}
pub fn column(&self) -> c_int {
self.column
}
pub fn id(&self) -> usize {
self.internal_id
}
}

32
tests/test_object.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "test_object_rust.h"
#include <QTest>
class TestRustObject : public QObject
{
Q_OBJECT
private slots:
void testConstructor();
void testStringGetter();
void testStringSetter();
};
void TestRustObject::testConstructor()
{
Person person;
}
void TestRustObject::testStringGetter()
{
Person person;
person.setUserName("Konqi");
}
void TestRustObject::testStringSetter()
{
Person person;
person.setUserName("Konqi");
QCOMPARE(person.userName(), QString("Konqi"));
}
QTEST_MAIN(TestRustObject)
#include "test_object.moc"

17
tests/test_object.json Normal file
View File

@ -0,0 +1,17 @@
{
"cppFile": "test_object_rust.cpp",
"rust": {
"dir": "rust_object",
"interfaceModule": "interface",
"implementationModule": "implementation"
},
"objects": [{
"name": "Person",
"type": "Object",
"properties": [{
"name": "userName",
"type": "QString",
"write": true
}]
}]
}

132
tests/test_object_rust.cpp Normal file
View File

@ -0,0 +1,132 @@
/* generated by rust_qt_binding_generator */
#include "test_object_rust.h"
#include <QModelIndex>
namespace {
struct qbytearray_t {
private:
const char* data;
int len;
public:
qbytearray_t(const QByteArray& v):
data(v.data()),
len(v.size()) {
}
operator QByteArray() const {
return QByteArray(data, len);
}
};
struct qstring_t {
private:
const void* data;
int len;
public:
qstring_t(const QString& v):
data(static_cast<const void*>(v.utf16())),
len(v.size()) {
}
operator QString() const {
return QString::fromUtf8(static_cast<const char*>(data), len);
}
};
struct qmodelindex_t {
int row;
int column;
uint64_t id;
qmodelindex_t(const QModelIndex& m):
row(m.row()), column(m.column()), id(m.internalId()) {}
};
struct qvariant_t {
unsigned int type;
int value;
const char* data;
};
QVariant variant(const qvariant_t& v) {
switch (v.type) {
case QVariant::Bool: return QVariant((bool)v.value);
case QVariant::String: return QString::fromUtf8(static_cast<const char*>(v.data), v.value);
default:;
}
return QVariant();
}
void variant(const QByteArray& v, void* d, void (*set)(void*, qvariant_t)) {
set(d, {
.type = QVariant::ByteArray,
.value = v.length(),
.data = v.data()
});
}
void variant(const QString& v, void* d, void (*set)(void*, qvariant_t)) {
set(d, {
.type = QVariant::String,
.value = v.size(),
.data = static_cast<const char*>(static_cast<const void*>(v.utf16()))
});
}
void variant(const QVariant& v, void* d, void (*set)(void*, qvariant_t)) {
switch (v.type()) {
case QVariant::Bool:
set(d, {
.type = QVariant::Bool,
.value = v.toBool(),
.data = 0
});
break;
case QVariant::Int:
set(d, {
.type = QVariant::Int,
.value = v.toInt(),
.data = 0
});
break;
case QVariant::ByteArray:
variant(v.toByteArray(), d, set);
break;
case QVariant::String:
variant(v.toString(), d, set);
break;
default:
set(d, {
.type = QVariant::Invalid,
.value = 0,
.data = 0
});
}
}
}
typedef void (*qstring_set)(QString*, qstring_t*);
void set_qstring(QString* v, qstring_t* val) {
*v = *val;
}
typedef void (*qbytearray_set)(QByteArray*, qbytearray_t*);
void set_qbytearray(QByteArray* v, qbytearray_t* val) {
*v = *val;
}
typedef void (*qvariant_set)(QVariant*, qvariant_t*);
void set_qvariant(QVariant* v, qvariant_t* val) {
*v = variant(*val);
}
extern "C" {
PersonInterface* person_new(Person*, void (*)(Person*));
void person_free(PersonInterface*);
void person_user_name_get(PersonInterface*, QString*, qstring_set);
void person_user_name_set(void*, qstring_t);
};
Person::Person(QObject *parent):
QObject(parent),
d(person_new(this,
[](Person* o) { emit o->userNameChanged(); })) {}
Person::~Person() {
person_free(d);
}
QString Person::userName() const
{
QString v;
person_user_name_get(d, &v, set_qstring);
return v;
}
void Person::setUserName(const QString& v) {
person_user_name_set(d, v);
}

25
tests/test_object_rust.h Normal file
View File

@ -0,0 +1,25 @@
/* generated by rust_qt_binding_generator */
#ifndef TEST_OBJECT_RUST_H
#define TEST_OBJECT_RUST_H
#include <QObject>
#include <QVariant>
#include <QAbstractItemModel>
class PersonInterface;
class Person : public QObject
{
Q_OBJECT
PersonInterface * const d;
Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged FINAL)
public:
explicit Person(QObject *parent = nullptr);
~Person();
QString userName() const;
void setUserName(const QString& v);
signals:
void userNameChanged();
private:
QString m_userName;
};
#endif // TEST_OBJECT_RUST_H