Make complex types optionally optional
parent
badea81a87
commit
726e52a81a
|
@ -97,7 +97,7 @@ pub struct RGeneralItemModel<T: Item> {
|
|||
emit: TreeEmitter,
|
||||
model: TreeUniformTree,
|
||||
entries: Vec<Entry<T>>,
|
||||
path: String,
|
||||
path: Option<String>,
|
||||
incoming: Incoming<T>,
|
||||
}
|
||||
|
||||
|
@ -115,17 +115,20 @@ impl<T: Item> RGeneralItemModel<T> where T: Sync + Send {
|
|||
let none1 = Entry {
|
||||
parent: 0,
|
||||
row: 0,
|
||||
children: Some(vec![2]),
|
||||
children: None,
|
||||
data: T::default(),
|
||||
};
|
||||
self.entries.push(none1);
|
||||
let root = Entry {
|
||||
parent: 1,
|
||||
row: 0,
|
||||
children: None,
|
||||
data: T::create(&self.path),
|
||||
};
|
||||
self.entries.push(root);
|
||||
if let Some(ref path) = self.path {
|
||||
self.entries[1].children = Some(vec![2]);
|
||||
let root = Entry {
|
||||
parent: 1,
|
||||
row: 0,
|
||||
children: None,
|
||||
data: T::create(&path),
|
||||
};
|
||||
self.entries.push(root);
|
||||
}
|
||||
self.model.end_reset_model();
|
||||
}
|
||||
fn get_index(&self, row: c_int, parent: usize) -> Option<usize> {
|
||||
|
@ -197,7 +200,7 @@ impl<T: Item> TreeTrait for RGeneralItemModel<T> where T: Sync + Send {
|
|||
emit: emit,
|
||||
model: model,
|
||||
entries: Vec::new(),
|
||||
path: String::new(),
|
||||
path: None,
|
||||
incoming: Arc::new(Mutex::new(HashMap::new()))
|
||||
};
|
||||
tree.reset();
|
||||
|
@ -206,10 +209,10 @@ impl<T: Item> TreeTrait for RGeneralItemModel<T> where T: Sync + Send {
|
|||
fn emit(&self) -> &TreeEmitter {
|
||||
&self.emit
|
||||
}
|
||||
fn get_path(&self) -> String {
|
||||
fn get_path(&self) -> Option<String> {
|
||||
self.path.clone()
|
||||
}
|
||||
fn set_path(&mut self, value: String) {
|
||||
fn set_path(&mut self, value: Option<String>) {
|
||||
if self.path != value {
|
||||
self.path = value;
|
||||
self.emit.path_changed();
|
||||
|
@ -263,8 +266,8 @@ impl<T: Item> TreeTrait for RGeneralItemModel<T> where T: Sync + Send {
|
|||
fn file_icon(&self, row: c_int, parent: usize) -> Vec<u8> {
|
||||
Vec::new()
|
||||
}
|
||||
fn file_path(&self, row: c_int, parent: usize) -> String {
|
||||
String::new()
|
||||
fn file_path(&self, row: c_int, parent: usize) -> Option<String> {
|
||||
None
|
||||
}
|
||||
fn file_type(&self, row: c_int, parent: usize) -> c_int {
|
||||
self.get(row, parent)
|
||||
|
|
|
@ -72,15 +72,15 @@ impl TreeUniformTree {
|
|||
pub trait TreeTrait {
|
||||
fn create(emit: TreeEmitter, model: TreeUniformTree) -> Self;
|
||||
fn emit(&self) -> &TreeEmitter;
|
||||
fn get_path(&self) -> String;
|
||||
fn set_path(&mut self, value: String);
|
||||
fn get_path(&self) -> Option<String>;
|
||||
fn set_path(&mut self, value: Option<String>);
|
||||
fn row_count(&self, row: c_int, parent: usize) -> c_int;
|
||||
fn can_fetch_more(&self, c_int, usize) -> bool { false }
|
||||
fn fetch_more(&mut self, c_int, usize) {}
|
||||
fn sort(&mut self, c_int, SortOrder) {}
|
||||
fn file_name(&self, row: c_int, parent: usize) -> String;
|
||||
fn file_icon(&self, row: c_int, parent: usize) -> Vec<u8>;
|
||||
fn file_path(&self, row: c_int, parent: usize) -> String;
|
||||
fn file_path(&self, row: c_int, parent: usize) -> Option<String>;
|
||||
fn file_permissions(&self, row: c_int, parent: usize) -> i32;
|
||||
fn file_type(&self, row: c_int, parent: usize) -> i32;
|
||||
fn file_size(&self, row: c_int, parent: usize) -> u64;
|
||||
|
@ -131,12 +131,14 @@ pub unsafe extern "C" fn tree_path_get(ptr: *const Tree,
|
|||
p: *mut c_void,
|
||||
set: fn(*mut c_void, QString)) {
|
||||
let data = (&*ptr).get_path();
|
||||
set(p, QString::from(&data));
|
||||
if let Some(data) = data {
|
||||
set(p, QString::from(&data));
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn tree_path_set(ptr: *mut Tree, v: QStringIn) {
|
||||
(&mut *ptr).set_path(v.convert());
|
||||
(&mut *ptr).set_path(Some(v.convert()));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -180,7 +182,9 @@ pub unsafe extern "C" fn tree_data_file_path(ptr: *const Tree,
|
|||
d: *mut c_void,
|
||||
set: fn(*mut c_void, QString)) {
|
||||
let data = (&*ptr).file_path(row, parent);
|
||||
set(d, QString::from(&data));
|
||||
if let Some(data) = data {
|
||||
set(d, QString::from(&data));
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"properties": [{
|
||||
"name": "path",
|
||||
"type": "QString",
|
||||
"write": true
|
||||
"write": true,
|
||||
"optional": true
|
||||
}],
|
||||
"roles": [
|
||||
[{
|
||||
|
@ -26,7 +27,8 @@
|
|||
}, {
|
||||
"name": "filePath",
|
||||
"value": "Qt::UserRole + 1",
|
||||
"type": "QString"
|
||||
"type": "QString",
|
||||
"optional": true
|
||||
}, {
|
||||
"name": "fileName",
|
||||
"value": "Qt::UserRole + 2",
|
||||
|
@ -47,7 +49,8 @@
|
|||
[{
|
||||
"name": "filePath",
|
||||
"value": "Qt::DisplayRole",
|
||||
"type": "QString"
|
||||
"type": "QString",
|
||||
"optional": true
|
||||
}],
|
||||
[{
|
||||
"name": "filePermissions",
|
||||
|
|
|
@ -43,7 +43,7 @@ BindingTypeProperties simpleType(const char* name, const char* init) {
|
|||
.cppSetType = name,
|
||||
.cSetType = name,
|
||||
.rustType = name,
|
||||
.rustTypeInit = init
|
||||
.rustTypeInit = init,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ const QMap<BindingType, BindingTypeProperties>& bindingTypeProperties() {
|
|||
.cppSetType = "qint32",
|
||||
.cSetType = "qint32",
|
||||
.rustType = "i32",
|
||||
.rustTypeInit = "0"
|
||||
.rustTypeInit = "0",
|
||||
});
|
||||
f.insert(BindingType::UInt, {
|
||||
.name = "quint32",
|
||||
|
@ -96,12 +96,14 @@ struct Property {
|
|||
QString name;
|
||||
BindingTypeProperties type;
|
||||
bool write;
|
||||
bool optional;
|
||||
};
|
||||
|
||||
struct Role {
|
||||
QString name;
|
||||
QString value;
|
||||
BindingTypeProperties type;
|
||||
bool optional;
|
||||
};
|
||||
|
||||
struct Object {
|
||||
|
@ -140,12 +142,31 @@ BindingTypeProperties parseBindingType(const QString& value) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QString rustType(const T& p)
|
||||
{
|
||||
if (p.optional) {
|
||||
return "Option<" + p.type.rustType + ">";
|
||||
}
|
||||
return p.type.rustType;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QString rustTypeInit(const T& p)
|
||||
{
|
||||
if (p.optional) {
|
||||
return "None";
|
||||
}
|
||||
return p.type.rustTypeInit;
|
||||
}
|
||||
|
||||
Property
|
||||
parseProperty(const QJsonObject& json) {
|
||||
Property p;
|
||||
p.name = json.value("name").toString();
|
||||
p.type = parseBindingType(json.value("type").toString());
|
||||
p.write = json.value("write").toBool();
|
||||
p.optional = json.value("optional").toBool();
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -155,6 +176,7 @@ parseRole(const QJsonObject& json) {
|
|||
r.name = json.value("name").toString();
|
||||
r.value = json.value("value").toString();
|
||||
r.type = parseBindingType(json.value("type").toString());
|
||||
r.optional = json.value("optional").toBool();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -878,9 +900,9 @@ pub trait %1Trait {
|
|||
)").arg(o.name, modelStruct);
|
||||
for (const Property& p: o.properties) {
|
||||
const QString lc(snakeCase(p.name));
|
||||
r << QString(" fn get_%1(&self) -> %2;\n").arg(lc, p.type.rustType);
|
||||
r << QString(" fn get_%1(&self) -> %2;\n").arg(lc, rustType(p));
|
||||
if (p.write) {
|
||||
r << QString(" fn set_%1(&mut self, value: %2);\n").arg(lc, p.type.rustType);
|
||||
r << QString(" fn set_%1(&mut self, value: %2);\n").arg(lc, rustType(p));
|
||||
}
|
||||
}
|
||||
if (o.type != ObjectType::Object) {
|
||||
|
@ -903,7 +925,7 @@ pub trait %1Trait {
|
|||
}
|
||||
for (auto role: o.allRoles) {
|
||||
r << QString(" fn %1(&self%3) -> %2;\n")
|
||||
.arg(snakeCase(role.name), role.type.rustType, index);
|
||||
.arg(snakeCase(role.name), rustType(role), index);
|
||||
}
|
||||
}
|
||||
if (o.type == ObjectType::UniformTree) {
|
||||
|
@ -981,8 +1003,8 @@ pub unsafe extern "C" fn %2_free(ptr: *mut %1) {
|
|||
)").arg(o.name, lcname, model);
|
||||
for (const Property& p: o.properties) {
|
||||
const QString base = QString("%1_%2").arg(lcname, snakeCase(p.name));
|
||||
QString ret = ") -> " + p.type.rustType;
|
||||
if (p.type.isComplex()) {
|
||||
QString ret = ") -> " + rustType(p);
|
||||
if (p.type.isComplex() && !p.optional) {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %2_get(ptr: *const %1,
|
||||
|
@ -999,6 +1021,27 @@ pub unsafe extern "C" fn %2_get(ptr: *const %1,
|
|||
pub unsafe extern "C" fn %2_set(ptr: *mut %1, v: %4) {
|
||||
(&mut *ptr).set_%3(v.convert());
|
||||
}
|
||||
)").arg(o.name, base, snakeCase(p.name), type);
|
||||
}
|
||||
} else if (p.type.isComplex()) {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %2_get(ptr: *const %1,
|
||||
p: *mut c_void,
|
||||
set: fn(*mut c_void, %4)) {
|
||||
let data = (&*ptr).get_%3();
|
||||
if let Some(data) = data {
|
||||
set(p, %4::from(&data));
|
||||
}
|
||||
}
|
||||
)").arg(o.name, base, snakeCase(p.name), p.type.name);
|
||||
if (p.write) {
|
||||
const QString type = p.type.name == "QString" ? "QStringIn" : p.type.name;
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %2_set(ptr: *mut %1, v: %4) {
|
||||
(&mut *ptr).set_%3(Some(v.convert()));
|
||||
}
|
||||
)").arg(o.name, base, snakeCase(p.name), type);
|
||||
}
|
||||
} else {
|
||||
|
@ -1007,14 +1050,14 @@ pub unsafe extern "C" fn %2_set(ptr: *mut %1, v: %4) {
|
|||
pub unsafe extern "C" fn %2_get(ptr: *const %1) -> %4 {
|
||||
(&*ptr).get_%3()
|
||||
}
|
||||
)").arg(o.name, base, snakeCase(p.name), p.type.rustType);
|
||||
)").arg(o.name, base, snakeCase(p.name), rustType(p));
|
||||
if (p.write) {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %2_set(ptr: *mut %1, v: %4) {
|
||||
(&mut *ptr).set_%3(v);
|
||||
}
|
||||
)").arg(o.name, base, snakeCase(p.name), p.type.rustType);
|
||||
)").arg(o.name, base, snakeCase(p.name), rustType(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1048,7 +1091,7 @@ pub unsafe extern "C" fn %2_sort(ptr: *mut %1, column: c_int, order: SortOrder)
|
|||
index = ", parent";
|
||||
}
|
||||
for (auto role: o.allRoles) {
|
||||
if (role.type.isComplex()) {
|
||||
if (role.type.isComplex() && !role.optional) {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %2_data_%3(ptr: *const %1,
|
||||
|
@ -1058,6 +1101,19 @@ pub unsafe extern "C" fn %2_data_%3(ptr: *const %1,
|
|||
let data = (&*ptr).%3(row%6);
|
||||
set(d, %4::from(&data));
|
||||
}
|
||||
)").arg(o.name, lcname, snakeCase(role.name), role.type.name, indexDecl, index);
|
||||
} else if (role.type.isComplex()) {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn %2_data_%3(ptr: *const %1,
|
||||
row: c_int%5,
|
||||
d: *mut c_void,
|
||||
set: fn(*mut c_void, %4)) {
|
||||
let data = (&*ptr).%3(row%6);
|
||||
if let Some(data) = data {
|
||||
set(d, %4::from(&data));
|
||||
}
|
||||
}
|
||||
)").arg(o.name, lcname, snakeCase(role.name), role.type.name, indexDecl, index);
|
||||
} else {
|
||||
r << QString(R"(
|
||||
|
@ -1065,7 +1121,7 @@ pub unsafe extern "C" fn %2_data_%3(ptr: *const %1,
|
|||
pub unsafe extern "C" fn %2_data_%3(ptr: *const %1, row: c_int%5) -> %4 {
|
||||
(&*ptr).%3(row%6)
|
||||
}
|
||||
)").arg(o.name, lcname, snakeCase(role.name), role.type.rustType, indexDecl, index);
|
||||
)").arg(o.name, lcname, snakeCase(role.name), rustType(role), indexDecl, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1123,7 +1179,7 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
|
|||
}
|
||||
for (const Property& p: o.properties) {
|
||||
const QString lc(snakeCase(p.name));
|
||||
r << QString(" %1: %2,\n").arg(lc, p.type.rustType);
|
||||
r << QString(" %1: %2,\n").arg(lc, rustType(p));
|
||||
}
|
||||
r << "}\n\n";
|
||||
r << QString(R"(impl %1Trait for %1 {
|
||||
|
@ -1136,7 +1192,7 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
|
|||
}
|
||||
for (const Property& p: o.properties) {
|
||||
const QString lc(snakeCase(p.name));
|
||||
r << QString(" %1: %2,\n").arg(lc, p.type.rustTypeInit);
|
||||
r << QString(" %1: %2,\n").arg(lc, rustTypeInit(p));
|
||||
}
|
||||
r << QString(R"( }
|
||||
}
|
||||
|
@ -1146,7 +1202,7 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
|
|||
)").arg(o.name);
|
||||
for (const Property& p: o.properties) {
|
||||
const QString lc(snakeCase(p.name));
|
||||
r << QString(" fn get_%1(&self) -> %2 {\n").arg(lc, p.type.rustType);
|
||||
r << QString(" fn get_%1(&self) -> %2 {\n").arg(lc, rustType(p));
|
||||
if (p.type.isComplex()) {
|
||||
r << QString(" self.%1.clone()\n").arg(lc);
|
||||
} else {
|
||||
|
@ -1158,7 +1214,7 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
|
|||
self.%1 = value;
|
||||
self.emit.%1_changed();
|
||||
}
|
||||
)").arg(lc, p.type.rustType);
|
||||
)").arg(lc, rustType(p));
|
||||
}
|
||||
}
|
||||
if (o.type != ObjectType::Object) {
|
||||
|
@ -1172,8 +1228,8 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
|
|||
}
|
||||
for (auto role: o.allRoles) {
|
||||
r << QString(" fn %1(&self, row: c_int%3) -> %2 {\n")
|
||||
.arg(snakeCase(role.name), role.type.rustType, index);
|
||||
r << " " << role.type.rustTypeInit << "\n";
|
||||
.arg(snakeCase(role.name), rustType(role), index);
|
||||
r << " " << rustTypeInit(role) << "\n";
|
||||
r << " }\n";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ pub struct Object {
|
|||
uinteger: u32,
|
||||
u64: u64,
|
||||
string: String,
|
||||
optional_string: Option<String>,
|
||||
bytearray: Vec<u8>,
|
||||
optional_bytearray: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl ObjectTrait for Object {
|
||||
|
@ -25,7 +27,9 @@ impl ObjectTrait for Object {
|
|||
uinteger: 0,
|
||||
u64: 0,
|
||||
string: String::new(),
|
||||
optional_string: None,
|
||||
bytearray: Vec::new(),
|
||||
optional_bytearray: None,
|
||||
}
|
||||
}
|
||||
fn emit(&self) -> &ObjectEmitter {
|
||||
|
@ -66,6 +70,13 @@ impl ObjectTrait for Object {
|
|||
self.string = value;
|
||||
self.emit.string_changed();
|
||||
}
|
||||
fn get_optional_string(&self) -> Option<String> {
|
||||
self.optional_string.clone()
|
||||
}
|
||||
fn set_optional_string(&mut self, value: Option<String>) {
|
||||
self.optional_string = value;
|
||||
self.emit.optional_string_changed();
|
||||
}
|
||||
fn get_bytearray(&self) -> Vec<u8> {
|
||||
self.bytearray.clone()
|
||||
}
|
||||
|
@ -73,4 +84,11 @@ impl ObjectTrait for Object {
|
|||
self.bytearray = value;
|
||||
self.emit.bytearray_changed();
|
||||
}
|
||||
fn get_optional_bytearray(&self) -> Option<Vec<u8>> {
|
||||
self.optional_bytearray.clone()
|
||||
}
|
||||
fn set_optional_bytearray(&mut self, value: Option<Vec<u8>>) {
|
||||
self.optional_bytearray = value;
|
||||
self.emit.optional_bytearray_changed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@ pub struct ObjectEmitter {
|
|||
uinteger_changed: fn(*const ObjectQObject),
|
||||
u64_changed: fn(*const ObjectQObject),
|
||||
string_changed: fn(*const ObjectQObject),
|
||||
optional_string_changed: fn(*const ObjectQObject),
|
||||
bytearray_changed: fn(*const ObjectQObject),
|
||||
optional_bytearray_changed: fn(*const ObjectQObject),
|
||||
}
|
||||
|
||||
unsafe impl Send for ObjectEmitter {}
|
||||
|
@ -58,12 +60,24 @@ impl ObjectEmitter {
|
|||
(self.string_changed)(ptr);
|
||||
}
|
||||
}
|
||||
pub fn optional_string_changed(&self) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.optional_string_changed)(ptr);
|
||||
}
|
||||
}
|
||||
pub fn bytearray_changed(&self) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.bytearray_changed)(ptr);
|
||||
}
|
||||
}
|
||||
pub fn optional_bytearray_changed(&self) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.optional_bytearray_changed)(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ObjectTrait {
|
||||
|
@ -79,8 +93,12 @@ pub trait ObjectTrait {
|
|||
fn set_u64(&mut self, value: u64);
|
||||
fn get_string(&self) -> String;
|
||||
fn set_string(&mut self, value: String);
|
||||
fn get_optional_string(&self) -> Option<String>;
|
||||
fn set_optional_string(&mut self, value: Option<String>);
|
||||
fn get_bytearray(&self) -> Vec<u8>;
|
||||
fn set_bytearray(&mut self, value: Vec<u8>);
|
||||
fn get_optional_bytearray(&self) -> Option<Vec<u8>>;
|
||||
fn set_optional_bytearray(&mut self, value: Option<Vec<u8>>);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -90,7 +108,9 @@ pub extern "C" fn object_new(qobject: *const ObjectQObject,
|
|||
uinteger_changed: fn(*const ObjectQObject),
|
||||
u64_changed: fn(*const ObjectQObject),
|
||||
string_changed: fn(*const ObjectQObject),
|
||||
bytearray_changed: fn(*const ObjectQObject))
|
||||
optional_string_changed: fn(*const ObjectQObject),
|
||||
bytearray_changed: fn(*const ObjectQObject),
|
||||
optional_bytearray_changed: fn(*const ObjectQObject))
|
||||
-> *mut Object {
|
||||
let emit = ObjectEmitter {
|
||||
qobject: Arc::new(Mutex::new(qobject)),
|
||||
|
@ -99,7 +119,9 @@ pub extern "C" fn object_new(qobject: *const ObjectQObject,
|
|||
uinteger_changed: uinteger_changed,
|
||||
u64_changed: u64_changed,
|
||||
string_changed: string_changed,
|
||||
optional_string_changed: optional_string_changed,
|
||||
bytearray_changed: bytearray_changed,
|
||||
optional_bytearray_changed: optional_bytearray_changed,
|
||||
};
|
||||
let d = Object::create(emit);
|
||||
Box::into_raw(Box::new(d))
|
||||
|
@ -163,6 +185,21 @@ 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_optional_string_get(ptr: *const Object,
|
||||
p: *mut c_void,
|
||||
set: fn(*mut c_void, QString)) {
|
||||
let data = (&*ptr).get_optional_string();
|
||||
if let Some(data) = data {
|
||||
set(p, QString::from(&data));
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn object_optional_string_set(ptr: *mut Object, v: QStringIn) {
|
||||
(&mut *ptr).set_optional_string(Some(v.convert()));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn object_bytearray_get(ptr: *const Object,
|
||||
p: *mut c_void,
|
||||
|
@ -175,3 +212,18 @@ pub unsafe extern "C" fn object_bytearray_get(ptr: *const Object,
|
|||
pub unsafe extern "C" fn object_bytearray_set(ptr: *mut Object, v: QByteArray) {
|
||||
(&mut *ptr).set_bytearray(v.convert());
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn object_optional_bytearray_get(ptr: *const Object,
|
||||
p: *mut c_void,
|
||||
set: fn(*mut c_void, QByteArray)) {
|
||||
let data = (&*ptr).get_optional_bytearray();
|
||||
if let Some(data) = data {
|
||||
set(p, QByteArray::from(&data));
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn object_optional_bytearray_set(ptr: *mut Object, v: QByteArray) {
|
||||
(&mut *ptr).set_optional_bytearray(Some(v.convert()));
|
||||
}
|
||||
|
|
|
@ -7,19 +7,18 @@ class TestRustObjectTypes : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
// 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 testUint64();
|
||||
void testString();
|
||||
void testOptionalString();
|
||||
void testByteArray();
|
||||
void testOptionalByteArray();
|
||||
};
|
||||
|
||||
template <typename V, typename Set, typename Get, typename Changed>
|
||||
void testSetter(V v, Set set, Get get, Changed changed)
|
||||
void testSetter(const V v, Set set, Get get, Changed changed)
|
||||
{
|
||||
// GIVEN
|
||||
Object object;
|
||||
|
@ -82,20 +81,48 @@ void TestRustObjectTypes::testString()
|
|||
{
|
||||
testSetter(QString(), &Object::setString,
|
||||
&Object::string, &Object::stringChanged);
|
||||
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::testOptionalString()
|
||||
{
|
||||
testSetter(QString(), &Object::setOptionalString,
|
||||
&Object::optionalString, &Object::optionalStringChanged);
|
||||
testSetter(QString(""), &Object::setOptionalString,
|
||||
&Object::optionalString, &Object::optionalStringChanged);
|
||||
testSetter(QString("Konqi"), &Object::setOptionalString,
|
||||
&Object::optionalString, &Object::optionalStringChanged);
|
||||
testSetter(QString("$𐐷𤭢"), &Object::setOptionalString,
|
||||
&Object::optionalString, &Object::optionalStringChanged);
|
||||
}
|
||||
|
||||
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};
|
||||
testSetter(QByteArray(data, 0), &Object::setBytearray,
|
||||
&Object::bytearray, &Object::bytearrayChanged);
|
||||
testSetter(QByteArray(data, 10), &Object::setBytearray,
|
||||
&Object::bytearray, &Object::bytearrayChanged);
|
||||
}
|
||||
|
||||
void TestRustObjectTypes::testOptionalByteArray()
|
||||
{
|
||||
testSetter(QByteArray(), &Object::setOptionalBytearray,
|
||||
&Object::optionalBytearray, &Object::optionalBytearrayChanged);
|
||||
const char data[10] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9};
|
||||
qDebug() << (QByteArray().data() == 0);
|
||||
testSetter(QByteArray(data, 0), &Object::setOptionalBytearray,
|
||||
&Object::optionalBytearray, &Object::optionalBytearrayChanged);
|
||||
testSetter(QByteArray(data, 10), &Object::setOptionalBytearray,
|
||||
&Object::optionalBytearray, &Object::optionalBytearrayChanged);
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestRustObjectTypes)
|
||||
#include "test_object_types.moc"
|
||||
|
|
|
@ -28,11 +28,22 @@
|
|||
}, {
|
||||
"name": "string",
|
||||
"type": "QString",
|
||||
"write": true
|
||||
"write": true,
|
||||
"nullable": true
|
||||
}, {
|
||||
"name": "optionalString",
|
||||
"type": "QString",
|
||||
"write": true,
|
||||
"optional": true
|
||||
}, {
|
||||
"name": "bytearray",
|
||||
"type": "QByteArray",
|
||||
"write": true
|
||||
}, {
|
||||
"name": "optionalBytearray",
|
||||
"type": "QByteArray",
|
||||
"write": true,
|
||||
"optional": true
|
||||
}]
|
||||
}]
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ void set_qbytearray(QByteArray* v, qbytearray_t* val) {
|
|||
}
|
||||
|
||||
extern "C" {
|
||||
Object::Private* object_new(Object*, void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*));
|
||||
Object::Private* object_new(Object*, void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*));
|
||||
void object_free(Object::Private*);
|
||||
bool object_boolean_get(const Object::Private*);
|
||||
void object_boolean_set(Object::Private*, bool);
|
||||
|
@ -55,8 +55,12 @@ extern "C" {
|
|||
void object_u64_set(Object::Private*, quint64);
|
||||
void object_string_get(const Object::Private*, QString*, qstring_set);
|
||||
void object_string_set(Object::Private*, qstring_t);
|
||||
void object_optional_string_get(const Object::Private*, QString*, qstring_set);
|
||||
void object_optional_string_set(Object::Private*, qstring_t);
|
||||
void object_bytearray_get(const Object::Private*, QByteArray*, qbytearray_set);
|
||||
void object_bytearray_set(Object::Private*, qbytearray_t);
|
||||
void object_optional_bytearray_get(const Object::Private*, QByteArray*, qbytearray_set);
|
||||
void object_optional_bytearray_set(Object::Private*, qbytearray_t);
|
||||
};
|
||||
Object::Object(QObject *parent):
|
||||
QObject(parent),
|
||||
|
@ -66,7 +70,9 @@ Object::Object(QObject *parent):
|
|||
[](Object* o) { emit o->uintegerChanged(); },
|
||||
[](Object* o) { emit o->u64Changed(); },
|
||||
[](Object* o) { emit o->stringChanged(); },
|
||||
[](Object* o) { emit o->bytearrayChanged(); })) {}
|
||||
[](Object* o) { emit o->optionalStringChanged(); },
|
||||
[](Object* o) { emit o->bytearrayChanged(); },
|
||||
[](Object* o) { emit o->optionalBytearrayChanged(); })) {}
|
||||
|
||||
Object::~Object() {
|
||||
object_free(d);
|
||||
|
@ -108,6 +114,15 @@ QString Object::string() const
|
|||
void Object::setString(const QString& v) {
|
||||
object_string_set(d, v);
|
||||
}
|
||||
QString Object::optionalString() const
|
||||
{
|
||||
QString v;
|
||||
object_optional_string_get(d, &v, set_qstring);
|
||||
return v;
|
||||
}
|
||||
void Object::setOptionalString(const QString& v) {
|
||||
object_optional_string_set(d, v);
|
||||
}
|
||||
QByteArray Object::bytearray() const
|
||||
{
|
||||
QByteArray v;
|
||||
|
@ -117,3 +132,12 @@ QByteArray Object::bytearray() const
|
|||
void Object::setBytearray(const QByteArray& v) {
|
||||
object_bytearray_set(d, v);
|
||||
}
|
||||
QByteArray Object::optionalBytearray() const
|
||||
{
|
||||
QByteArray v;
|
||||
object_optional_bytearray_get(d, &v, set_qbytearray);
|
||||
return v;
|
||||
}
|
||||
void Object::setOptionalBytearray(const QByteArray& v) {
|
||||
object_optional_bytearray_set(d, v);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,9 @@ private:
|
|||
Q_PROPERTY(quint32 uinteger READ uinteger WRITE setUinteger NOTIFY uintegerChanged FINAL)
|
||||
Q_PROPERTY(quint64 u64 READ u64 WRITE setU64 NOTIFY u64Changed FINAL)
|
||||
Q_PROPERTY(QString string READ string WRITE setString NOTIFY stringChanged FINAL)
|
||||
Q_PROPERTY(QString optionalString READ optionalString WRITE setOptionalString NOTIFY optionalStringChanged FINAL)
|
||||
Q_PROPERTY(QByteArray bytearray READ bytearray WRITE setBytearray NOTIFY bytearrayChanged FINAL)
|
||||
Q_PROPERTY(QByteArray optionalBytearray READ optionalBytearray WRITE setOptionalBytearray NOTIFY optionalBytearrayChanged FINAL)
|
||||
public:
|
||||
explicit Object(QObject *parent = nullptr);
|
||||
~Object();
|
||||
|
@ -31,21 +33,29 @@ public:
|
|||
void setU64(quint64 v);
|
||||
QString string() const;
|
||||
void setString(const QString& v);
|
||||
QString optionalString() const;
|
||||
void setOptionalString(const QString& v);
|
||||
QByteArray bytearray() const;
|
||||
void setBytearray(const QByteArray& v);
|
||||
QByteArray optionalBytearray() const;
|
||||
void setOptionalBytearray(const QByteArray& v);
|
||||
signals:
|
||||
void booleanChanged();
|
||||
void integerChanged();
|
||||
void uintegerChanged();
|
||||
void u64Changed();
|
||||
void stringChanged();
|
||||
void optionalStringChanged();
|
||||
void bytearrayChanged();
|
||||
void optionalBytearrayChanged();
|
||||
private:
|
||||
bool m_boolean;
|
||||
qint32 m_integer;
|
||||
quint32 m_uinteger;
|
||||
quint64 m_u64;
|
||||
QString m_string;
|
||||
QString m_optionalString;
|
||||
QByteArray m_bytearray;
|
||||
QByteArray m_optionalBytearray;
|
||||
};
|
||||
#endif // TEST_OBJECT_TYPES_RUST_H
|
||||
|
|
Loading…
Reference in New Issue