slint
slint copied to clipboard
Ability to import Rust and C++ struct as .slint struct
Something like (in slint)
import { MyNamespace::MyStruct as MyStruct } form "../include/some_file.h";
import { crate::foo::bar::SomeOtherStruct as SomeStruct } from "../some/module/foo.rs";
The slint compiler would use the syn crate to parse the rust file, or some simple C++ parser to parse the header file.
The struct themselves needs to be Clone, Default, Eq (and equivalent in C++) and only have public fields of type that are understood by Slint (without typedef or use or stuff, as the parser will stay simple)
This would be great for instance when I want to derive Serialize and Deserialize for a struct that I'm using in a slint file.
It's useful,can use it by slint 0.3.1?
How will this work with interpreted Slint code ?
The idea is that the compiler will load and parse the C++/Rust file and extract the struct so that it works also in the preview/interpreter/...
For rust, we can use the syn
library to parse the code, that should be easy. But that also mean quite a big dependency for the js or wasm things that might not need it, so we should have it optional.
For C++, i don't know if there is a library that does this already that we can use. Maybe we'd be good with a simple lexer and find the struct Foo {
tokens or similar that don't care about C++ macros, or C++ concepts more than just structs with members.
You could also use libclang rust bindings (like https://github.com/KyleMayes/clang-sys ) to do this.
HI! Here's my use case, and I can't wait for you guys to implement a solution for this. I have a project structure like this one (repo)
/mod-template
│
├── crates/
│ ├── project/
│ │ ├──src/
│ │ │ └── main.rs
│ │ └── Cargo.toml
│ │
│ └── project-lib/
│ ├── src/
│ │ ├── components/
│ │ │ ├── comp1/
│ │ │ │ └── struct1.rs
│ │ │ ├── comp2/
│ │ │ │ └── struct2.rs
│ │ │ ├── comp1.rs
│ │ │ └── comp2.rs
│ │ ├── slint/
│ │ │ ├── building_blocks/
│ │ │ │ └── block1.rs
│ │ │ ├── widgets/
│ │ │ │ └── widget1.rs
│ │ │ ├── building_blocks.rs
│ │ │ └── widgets.rs
│ │ ├── components.rs
│ │ ├── slint.rs
│ │ ├── lib.rs
│ │ ├── main.rs
│ │ └── prelude.rs
│ ├── build.rs
│ └── Cargo.toml
├── Cargo.toml
└── Cargo.lock
Where I have two crates: "project" which contains the application itself and "project-lib" which is a library that holds the business logic and the UI widgets in Slint (slint macro and/or .slint file).
In the Slint/ directory, within slint macro or .slint file I can't use the business logic objects/structs. As you said, it will be awesome to import those structs as .slint structs. Also, accessing the methods of a struct so we can bind/alias a callback to an actual business logic function or just call that struct method:
import { crate::components::{Comp1, Comp2} } from "../some/module/foo.rs"; // not sure about the "from ..."
export component Example inherits Rectangle {
// declare a callback
property <Comp1> my_component;
callback hello <=> my_component.print_text("my comp1")
// or
// callback hello <=> my_component::print_text("my comp1")
area := TouchArea {
// sets a handler with `=>`
clicked => {
// emit the callback
root.hello()
}
}
}
Also, being able to cast structs, something like this:
struct TempStruct {
prop1,
prop2,
}
import { crate::components::{Comp1, Comp2} } from "../some/module/foo.rs"; // not sure about the "from ..."
// let say Comp1 has 6 properties
export component Example inherits Rectangle {
proprety<{prop1: string, prop2: Comp2}> simplified_obj: Comp1
// do something with the simplified object
}
For the above, I'm not sure about the syntax but I hope the idea is clear.
Hopefully this is coming down the line. At the moment it is very cumbersome to redefine structs in Slint, and then have rust code to translate the native struct into the slint struct via callback.