slint icon indicating copy to clipboard operation
slint copied to clipboard

Ability to import Rust and C++ struct as .slint struct

Open ogoffart opened this issue 2 years ago • 10 comments

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)

ogoffart avatar Oct 12 '22 08:10 ogoffart

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.

Sintrastes avatar Oct 15 '22 01:10 Sintrastes

It's useful,can use it by slint 0.3.1?

xiaodusx1 avatar Oct 28 '22 00:10 xiaodusx1

How will this work with interpreted Slint code ?

aamer-shaikh avatar Feb 03 '23 15:02 aamer-shaikh

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/...

ogoffart avatar Feb 03 '23 15:02 ogoffart

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.

ogoffart avatar Feb 03 '23 15:02 ogoffart

You could also use libclang rust bindings (like https://github.com/KyleMayes/clang-sys ) to do this.

erikjv avatar Apr 06 '23 18:04 erikjv

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.

sinkyl avatar Apr 19 '24 00:04 sinkyl

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.

GavinShox avatar Aug 04 '24 20:08 GavinShox