Intruduce rustByFunction
rustByFunction lets a getter get a value even if it is not possible to return a value by reference. rustByFunction passes a getter function in the getter. This can be called with the value instead of returning a reference.master
parent
ee5df0337b
commit
32fed925e9
|
@ -178,6 +178,7 @@ parseProperty(const QString& name, const QJsonObject& json) {
|
|||
p.write = json.value("write").toBool();
|
||||
p.optional = json.value("optional").toBool();
|
||||
p.rustByValue = json.value("rustByValue").toBool();
|
||||
p.rustByFunction = json.value("rustByFunction").toBool();
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
25
src/rust.cpp
25
src/rust.cpp
|
@ -331,7 +331,11 @@ pub trait %1Trait {
|
|||
r << QString(" fn %1(&self) -> &%2;\n").arg(lc, rustType(p));
|
||||
r << QString(" fn %1_mut(&mut self) -> &mut %2;\n").arg(lc, rustType(p));
|
||||
} else {
|
||||
r << QString(" fn %1(&self) -> %2;\n").arg(lc, rustReturnType(p));
|
||||
if (p.rustByFunction) {
|
||||
r << QString(" fn %1<F>(&self, getter: F) where F: FnOnce(%2);").arg(lc, rustReturnType(p));
|
||||
} else {
|
||||
r << QString(" fn %1(&self) -> %2;\n").arg(lc, rustReturnType(p));
|
||||
}
|
||||
if (p.write) {
|
||||
if (p.type.name == "QByteArray") {
|
||||
if (p.optional) {
|
||||
|
@ -428,7 +432,23 @@ pub unsafe extern "C" fn %2_get(ptr: *mut %1) -> *mut %4 {
|
|||
)").arg(o.name, base, snakeCase(p.name), rustType(p));
|
||||
|
||||
} else if (p.type.isComplex() && !p.optional) {
|
||||
r << QString(R"(
|
||||
if (p.rustByFunction) {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn %2_get(
|
||||
ptr: *const %1,
|
||||
p: *mut %4,
|
||||
set: fn(*mut %4, *const c_char, c_int),
|
||||
) {
|
||||
let o = unsafe { &*ptr };
|
||||
o.%3(|v| {
|
||||
let s: *const c_char = v.as_ptr() as (*const c_char);
|
||||
set(p, s, to_c_int(v.len()));
|
||||
});
|
||||
}
|
||||
)").arg(o.name, base, snakeCase(p.name), p.type.name);
|
||||
} else {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn %2_get(
|
||||
ptr: *const %1,
|
||||
|
@ -441,6 +461,7 @@ pub extern "C" fn %2_get(
|
|||
set(p, s, to_c_int(v.len()));
|
||||
}
|
||||
)").arg(o.name, base, snakeCase(p.name), p.type.name);
|
||||
}
|
||||
if (p.write && p.type.name == "QString") {
|
||||
r << QString(R"(
|
||||
#[no_mangle]
|
||||
|
|
|
@ -76,6 +76,7 @@ struct Property {
|
|||
bool write;
|
||||
bool optional;
|
||||
bool rustByValue;
|
||||
bool rustByFunction;
|
||||
};
|
||||
|
||||
struct Argument {
|
||||
|
|
|
@ -22,6 +22,7 @@ pub struct Object {
|
|||
optional_bytearray: Option<Vec<u8>>,
|
||||
string: String,
|
||||
optional_string: Option<String>,
|
||||
string_by_function: String,
|
||||
}
|
||||
|
||||
impl ObjectTrait for Object {
|
||||
|
@ -44,7 +45,8 @@ impl ObjectTrait for Object {
|
|||
bytearray: Vec::new(),
|
||||
optional_bytearray: None,
|
||||
string: String::new(),
|
||||
optional_string: None
|
||||
optional_string: None,
|
||||
string_by_function: String::new()
|
||||
}
|
||||
}
|
||||
fn emit(&self) -> &ObjectEmitter {
|
||||
|
@ -179,5 +181,12 @@ impl ObjectTrait for Object {
|
|||
self.string = value;
|
||||
self.emit.string_changed();
|
||||
}
|
||||
fn string_by_function<F>(&self, getter: F) where F: FnOnce(&str) {
|
||||
getter(&self.string_by_function)
|
||||
}
|
||||
fn set_string_by_function(&mut self, value: String) {
|
||||
self.string_by_function = value;
|
||||
self.emit.string_by_function_changed();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ pub struct ObjectEmitter {
|
|||
optional_string_changed: fn(*const ObjectQObject),
|
||||
optional_u64_changed: fn(*const ObjectQObject),
|
||||
string_changed: fn(*const ObjectQObject),
|
||||
string_by_function_changed: fn(*const ObjectQObject),
|
||||
u16_changed: fn(*const ObjectQObject),
|
||||
u32_changed: fn(*const ObjectQObject),
|
||||
u64_changed: fn(*const ObjectQObject),
|
||||
|
@ -177,6 +178,12 @@ impl ObjectEmitter {
|
|||
(self.string_changed)(ptr);
|
||||
}
|
||||
}
|
||||
pub fn string_by_function_changed(&self) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
(self.string_by_function_changed)(ptr);
|
||||
}
|
||||
}
|
||||
pub fn u16_changed(&self) {
|
||||
let ptr = *self.qobject.lock().unwrap();
|
||||
if !ptr.is_null() {
|
||||
|
@ -232,6 +239,7 @@ pub trait ObjectTrait {
|
|||
fn set_optional_u64(&mut self, value: Option<u64>);
|
||||
fn string(&self) -> &str;
|
||||
fn set_string(&mut self, value: String);
|
||||
fn string_by_function<F>(&self, getter: F) where F: FnOnce(&str); fn set_string_by_function(&mut self, value: String);
|
||||
fn u16(&self) -> u16;
|
||||
fn set_u16(&mut self, value: u16);
|
||||
fn u32(&self) -> u32;
|
||||
|
@ -258,6 +266,7 @@ pub extern "C" fn object_new(
|
|||
object_optional_string_changed: fn(*const ObjectQObject),
|
||||
object_optional_u64_changed: fn(*const ObjectQObject),
|
||||
object_string_changed: fn(*const ObjectQObject),
|
||||
object_string_by_function_changed: fn(*const ObjectQObject),
|
||||
object_u16_changed: fn(*const ObjectQObject),
|
||||
object_u32_changed: fn(*const ObjectQObject),
|
||||
object_u64_changed: fn(*const ObjectQObject),
|
||||
|
@ -278,6 +287,7 @@ pub extern "C" fn object_new(
|
|||
optional_string_changed: object_optional_string_changed,
|
||||
optional_u64_changed: object_optional_u64_changed,
|
||||
string_changed: object_string_changed,
|
||||
string_by_function_changed: object_string_by_function_changed,
|
||||
u16_changed: object_u16_changed,
|
||||
u32_changed: object_u32_changed,
|
||||
u64_changed: object_u64_changed,
|
||||
|
@ -494,6 +504,27 @@ pub extern "C" fn object_string_set(ptr: *mut Object, v: *const c_ushort, len: c
|
|||
o.set_string(s);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn object_string_by_function_get(
|
||||
ptr: *const Object,
|
||||
p: *mut QString,
|
||||
set: fn(*mut QString, *const c_char, c_int),
|
||||
) {
|
||||
let o = unsafe { &*ptr };
|
||||
o.string_by_function(|v| {
|
||||
let s: *const c_char = v.as_ptr() as (*const c_char);
|
||||
set(p, s, to_c_int(v.len()));
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn object_string_by_function_set(ptr: *mut Object, v: *const c_ushort, len: c_int) {
|
||||
let o = unsafe { &mut *ptr };
|
||||
let mut s = String::new();
|
||||
set_string_from_utf16(&mut s, v, len);
|
||||
o.set_string_by_function(s);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn object_u16_get(ptr: *const Object) -> u16 {
|
||||
(&*ptr).u16()
|
||||
|
|
|
@ -24,6 +24,7 @@ private slots:
|
|||
void testOptionalString();
|
||||
void testByteArray();
|
||||
void testOptionalByteArray();
|
||||
void testStringByFunction();
|
||||
};
|
||||
|
||||
template <typename V, typename Set, typename Get, typename Changed>
|
||||
|
@ -208,6 +209,18 @@ void TestRustObjectTypes::testString()
|
|||
&Object::string, &Object::stringChanged);
|
||||
}
|
||||
|
||||
void TestRustObjectTypes::testStringByFunction()
|
||||
{
|
||||
testSetter(QString(), &Object::setStringByFunction,
|
||||
&Object::stringByFunction, &Object::stringByFunctionChanged);
|
||||
testSetter(QString(""), &Object::setStringByFunction,
|
||||
&Object::stringByFunction, &Object::stringByFunctionChanged);
|
||||
testSetter(QString("Konqi"), &Object::setStringByFunction,
|
||||
&Object::stringByFunction, &Object::stringByFunctionChanged);
|
||||
testSetter(QString("$𐐷𤭢"), &Object::setStringByFunction,
|
||||
&Object::stringByFunction, &Object::stringByFunctionChanged);
|
||||
}
|
||||
|
||||
void TestRustObjectTypes::testOptionalString()
|
||||
{
|
||||
testSetter(QString(), &Object::setOptionalString,
|
||||
|
|
|
@ -80,6 +80,11 @@
|
|||
"type": "QByteArray",
|
||||
"write": true,
|
||||
"optional": true
|
||||
},
|
||||
"stringByFunction": {
|
||||
"type": "QString",
|
||||
"write": true,
|
||||
"rustByFunction": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,10 @@ namespace {
|
|||
{
|
||||
emit o->stringChanged();
|
||||
}
|
||||
inline void objectStringByFunctionChanged(Object* o)
|
||||
{
|
||||
emit o->stringByFunctionChanged();
|
||||
}
|
||||
inline void objectU16Changed(Object* o)
|
||||
{
|
||||
emit o->u16Changed();
|
||||
|
@ -113,7 +117,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
extern "C" {
|
||||
Object::Private* object_new(Object*, void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(Object*), void (*)(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*), void (*)(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);
|
||||
|
@ -145,6 +149,8 @@ extern "C" {
|
|||
void object_optional_u64_set_none(Object::Private*);
|
||||
void object_string_get(const Object::Private*, QString*, qstring_set);
|
||||
void object_string_set(Object::Private*, const ushort *str, int len);
|
||||
void object_string_by_function_get(const Object::Private*, QString*, qstring_set);
|
||||
void object_string_by_function_set(Object::Private*, const ushort *str, int len);
|
||||
quint16 object_u16_get(const Object::Private*);
|
||||
void object_u16_set(Object::Private*, quint16);
|
||||
quint32 object_u32_get(const Object::Private*);
|
||||
|
@ -178,6 +184,7 @@ Object::Object(QObject *parent):
|
|||
objectOptionalStringChanged,
|
||||
objectOptionalU64Changed,
|
||||
objectStringChanged,
|
||||
objectStringByFunctionChanged,
|
||||
objectU16Changed,
|
||||
objectU32Changed,
|
||||
objectU64Changed,
|
||||
|
@ -316,6 +323,15 @@ QString Object::string() const
|
|||
void Object::setString(const QString& v) {
|
||||
object_string_set(m_d, reinterpret_cast<const ushort*>(v.data()), v.size());
|
||||
}
|
||||
QString Object::stringByFunction() const
|
||||
{
|
||||
QString v;
|
||||
object_string_by_function_get(m_d, &v, set_qstring);
|
||||
return v;
|
||||
}
|
||||
void Object::setStringByFunction(const QString& v) {
|
||||
object_string_by_function_set(m_d, reinterpret_cast<const ushort*>(v.data()), v.size());
|
||||
}
|
||||
quint16 Object::u16() const
|
||||
{
|
||||
return object_u16_get(m_d);
|
||||
|
|
|
@ -28,6 +28,7 @@ private:
|
|||
Q_PROPERTY(QString optionalString READ optionalString WRITE setOptionalString NOTIFY optionalStringChanged FINAL)
|
||||
Q_PROPERTY(QVariant optionalU64 READ optionalU64 WRITE setOptionalU64 NOTIFY optionalU64Changed FINAL)
|
||||
Q_PROPERTY(QString string READ string WRITE setString NOTIFY stringChanged FINAL)
|
||||
Q_PROPERTY(QString stringByFunction READ stringByFunction WRITE setStringByFunction NOTIFY stringByFunctionChanged FINAL)
|
||||
Q_PROPERTY(quint16 u16 READ u16 WRITE setU16 NOTIFY u16Changed FINAL)
|
||||
Q_PROPERTY(quint32 u32 READ u32 WRITE setU32 NOTIFY u32Changed FINAL)
|
||||
Q_PROPERTY(quint64 u64 READ u64 WRITE setU64 NOTIFY u64Changed FINAL)
|
||||
|
@ -62,6 +63,8 @@ public:
|
|||
void setOptionalU64(const QVariant& v);
|
||||
QString string() const;
|
||||
void setString(const QString& v);
|
||||
QString stringByFunction() const;
|
||||
void setStringByFunction(const QString& v);
|
||||
quint16 u16() const;
|
||||
void setU16(quint16 v);
|
||||
quint32 u32() const;
|
||||
|
@ -84,6 +87,7 @@ signals:
|
|||
void optionalStringChanged();
|
||||
void optionalU64Changed();
|
||||
void stringChanged();
|
||||
void stringByFunctionChanged();
|
||||
void u16Changed();
|
||||
void u32Changed();
|
||||
void u64Changed();
|
||||
|
|
Loading…
Reference in New Issue