Documentation
# Slint development guide

The build instructions are in the [building.md](./building.md) file.
The testing instructions are in the [testing.md](./testing.md) file.

## Repository structures

### `helper_crates`

A set of crates that are somehow not strictly related to Slint, and that could be moved to
their own repository and have their own version release at some point.

### `internal`

`internal` contains code that is not meant to be used directly by a user of Slint.

#### `compiler`

The main library for the compiler for .slint.

Nothing in there should depends on the runtime crates.

There is a **`test`** subdirectory that contains the syntax tests.
These tests allow to test the proper error conditions.

#### Runtime libraries

The library crates that are used at runtime.

* **`core`** is the main library. It is meant to be used for all front-ends. Ideally it should
  be kept as small as possible. **`corelib-macros`** contains some procedural macro used by core library.
* **`backends`** contains the different backend for the different platform, separated from
  core library.  Currently there is just the gl backend
* **`interpreter`** is the library used by the more dynamic languages backend to compile and
  interpret .slint files. It links both against core library and the compiler lib

### `tools`

* **`compiler`** is the tool to generate the target language (e.g. c++) from the .slint files for
  frontend that have a compilation step and generated code.
* **`viewer`** is a tool that allow to open and view a .slint file.

### `api`

Here one find the frontend for different language.

### `tests`

The integration test that are testing a bunch of .slint with different front-ends

See [testing.md](./testing.md)

### `examples`

Some manual tests

## Documentation

There are some documentations comments in the code.
HTML documentation can be generated with something like

```sh
cargo doc --document-private-items --no-deps --open
```

## Rust to C++ bindings

We use a rather complex mechanism to expose internal data structures implemented in Rust to C++, in a way that allows us to provide a nice C++ API.

As a starting point, we recommend reading the blog entry we published about this:

[https://slint-ui.com/blog/expose-rust-library-to-other-languages.html](https://slint-ui.com/blog/expose-rust-library-to-other-languages.html)

What this article omits are how we invoke cbindgen and what kind of tweaks we apply on various levels:

The C++ library consists of four components:

1. The `slint-cpp` cdylib created by `cargo`/`rustc` from `api/cpp`.
1. The public header files in `api/cpp/include`.
1. Internal header files generated by `cbindgen`, via `cargo xtask cbindgen`.
1. The CMake project to tie it all together by invoking `corrosion` to call `cargo` and invoking `cbindgen`.

### `cbindgen`

The `cbindgen` xtask generates multiple header files for four different modules:

1. The types in the core library. This is the bulk of the generated code.
1. The entry points into the C++ library for creating backends, invoking the event loop, etc. - from `api/cpp/lib.rs`.
1. The types specific to the Qt backend used by the Qt style, such as `NativeButton`, etc.
1. The types used by the C++ interpreter API, written to `slint_interpreter_internal.h`.

Typically the input to `cbindgen` is within `ffi` sub-modules in the corresponding input crates to `cbindgen`. These `ffi` modules are gated with `#[cfg(feature = "ffi")]`.