Progress towards generating rust interface
parent
77a58075c2
commit
ff2a0a1f70
|
@ -1,5 +1,10 @@
|
||||||
{
|
{
|
||||||
"cppfile": "src/tmp.cpp",
|
"cppfile": "src/tmp.cpp",
|
||||||
|
"rust": {
|
||||||
|
"dir": "common-rust",
|
||||||
|
"interfacemodule": "testinterface",
|
||||||
|
"implementationmodule": "testimplementation"
|
||||||
|
},
|
||||||
"objects": [{
|
"objects": [{
|
||||||
"name": "Test",
|
"name": "Test",
|
||||||
"properties": [{
|
"properties": [{
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
pub mod testinterface;
|
||||||
|
pub mod testimplementation;
|
||||||
pub mod interface;
|
pub mod interface;
|
||||||
pub mod implementation;
|
pub mod implementation;
|
||||||
|
|
|
@ -25,6 +25,9 @@ struct Object {
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
QFileInfo hfile;
|
QFileInfo hfile;
|
||||||
QFileInfo cppfile;
|
QFileInfo cppfile;
|
||||||
|
QDir rustdir;
|
||||||
|
QString interfacemodule;
|
||||||
|
QString implementationmodule;
|
||||||
QList<Object> objects;
|
QList<Object> objects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,6 +75,10 @@ parseConfiguration(const QString& path) {
|
||||||
for (const QJsonValue& val: o.value("objects").toArray()) {
|
for (const QJsonValue& val: o.value("objects").toArray()) {
|
||||||
c.objects.append(parseObject(val.toObject()));
|
c.objects.append(parseObject(val.toObject()));
|
||||||
}
|
}
|
||||||
|
const QJsonObject rust = o.value("rust").toObject();
|
||||||
|
c.rustdir = QDir(base.filePath(rust.value("dir").toString()));
|
||||||
|
c.interfacemodule = rust.value("interfacemodule").toString();
|
||||||
|
c.implementationmodule = rust.value("implementationmodule").toString();
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,6 +354,124 @@ extern "C" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString rustType(const Property& p) {
|
||||||
|
if (p.type == "QVariant") {
|
||||||
|
return "Variant";
|
||||||
|
}
|
||||||
|
if (p.type.startsWith("Q")) {
|
||||||
|
return "&" + p.type.mid(1);
|
||||||
|
}
|
||||||
|
if (p.type == "int") {
|
||||||
|
return "c_int";
|
||||||
|
}
|
||||||
|
return p.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeRustInterfaceObject(QTextStream& r, const Object& o) {
|
||||||
|
const QString lcname(o.name.toLower());
|
||||||
|
r << QString(R"(
|
||||||
|
pub struct %1QObject {}
|
||||||
|
|
||||||
|
#[derive (Clone)]
|
||||||
|
pub struct %1Emitter {
|
||||||
|
qobject: Arc<Mutex<*const %1QObject>>,
|
||||||
|
)").arg(o.name);
|
||||||
|
for (const Property& p: o.properties) {
|
||||||
|
r << QString(" %2_changed: fn (*const %1QObject),\n")
|
||||||
|
.arg(o.name, p.name.toLower());
|
||||||
|
}
|
||||||
|
r << QString(R"(}
|
||||||
|
|
||||||
|
unsafe impl Send for %1Emitter {}
|
||||||
|
|
||||||
|
impl %1Emitter {
|
||||||
|
fn clear(&self) {
|
||||||
|
*self.qobject.lock().unwrap() = null();
|
||||||
|
}
|
||||||
|
)").arg(o.name);
|
||||||
|
for (const Property& p: o.properties) {
|
||||||
|
r << QString(R"( pub fn %1_changed(&self) {
|
||||||
|
let ptr = *self.qobject.lock().unwrap();
|
||||||
|
if !ptr.is_null() {
|
||||||
|
(self.%1_changed)(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)").arg(p.name.toLower());
|
||||||
|
}
|
||||||
|
|
||||||
|
r << QString(R"(}
|
||||||
|
|
||||||
|
pub trait %1Trait {
|
||||||
|
fn create(emit: %1Emitter) -> Self;
|
||||||
|
fn emit(&self) -> &%1Emitter;
|
||||||
|
)").arg(o.name);
|
||||||
|
for (const Property& p: o.properties) {
|
||||||
|
const QString lc(p.name.toLower());
|
||||||
|
const bool q = p.type.startsWith("Q");
|
||||||
|
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, rustType(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r << QString(R"(}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern fn %2_new(qobject: *const %1QObject)").arg(o.name, lcname);
|
||||||
|
for (const Property& p: o.properties) {
|
||||||
|
r << QString(",\n %2_changed: fn (*const %1QObject)")
|
||||||
|
.arg(o.name, p.name.toLower());
|
||||||
|
}
|
||||||
|
r << QString(R"() -> *mut %1 {
|
||||||
|
let emit = %1Emitter {
|
||||||
|
qobject: Arc::new(Mutex::new(qobject)))").arg(o.name);
|
||||||
|
for (const Property& p: o.properties) {
|
||||||
|
r << QString(",\n %1_changed: %1_changed").arg(p.name.toLower());
|
||||||
|
}
|
||||||
|
r << QString(R"(
|
||||||
|
};
|
||||||
|
let d = %1::create(emit);
|
||||||
|
Box::into_raw(Box::new(d))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern fn %2_free(ptr: *mut %1) {
|
||||||
|
let d = unsafe { Box::from_raw(ptr) };
|
||||||
|
d.emit().clear();
|
||||||
|
}
|
||||||
|
)").arg(o.name, lcname);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString rustFile(const QDir rustdir, const QString& module) {
|
||||||
|
QDir src(rustdir.absoluteFilePath("src"));
|
||||||
|
QString path = src.absoluteFilePath(module + ".rs");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeRustInterface(const Configuration& conf) {
|
||||||
|
QFile file(rustFile(conf.rustdir, conf.interfacemodule));
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
err << QCoreApplication::translate("main",
|
||||||
|
"Cannot write %1.\n").arg(file.fileName());
|
||||||
|
err.flush();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
QTextStream r(&file);
|
||||||
|
r << QString(R"(
|
||||||
|
use std::slice;
|
||||||
|
use libc::{c_int, uint16_t, size_t, c_void};
|
||||||
|
use types::*;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::ptr::null;
|
||||||
|
|
||||||
|
use %1::*;
|
||||||
|
)").arg(conf.implementationmodule);
|
||||||
|
|
||||||
|
for (auto object: conf.objects) {
|
||||||
|
writeRustInterfaceObject(r, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
QCoreApplication::setApplicationName(argv[0]);
|
QCoreApplication::setApplicationName(argv[0]);
|
||||||
|
@ -373,6 +498,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
writeHeader(configuration);
|
writeHeader(configuration);
|
||||||
writeCpp(configuration);
|
writeCpp(configuration);
|
||||||
|
writeRustInterface(configuration);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue