qtbridge_gen/lib.rs
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only
3
4use proc_macro::TokenStream;
5
6mod qt_derive;
7mod qt_gen_impl;
8mod qt_resource;
9
10#[proc_macro_attribute]
11pub fn qobject(args: TokenStream, input: TokenStream) -> TokenStream {
12 let mut builder = qt_gen_impl::QObjectModuleBuilder::new();
13 builder.build_token_stream(input.into(), args.into())
14 .unwrap_or_else(|err| err.to_compile_error())
15 .into()
16}
17
18#[proc_macro_attribute]
19pub fn qsignal(_: TokenStream, _: TokenStream) -> TokenStream {
20 // This macro does nothing but offer an entry point for Rust doc
21 panic!("#[qsignal] proc macro called outside #[qobject].")
22}
23
24#[proc_macro_attribute]
25pub fn qslot(_: TokenStream, _: TokenStream) -> TokenStream {
26 // This macro does nothing but offer an entry point for Rust doc
27 panic!("#[qslot] proc macro called outside #[qobject].")
28}
29
30#[proc_macro]
31pub fn qproperty(_: TokenStream) -> TokenStream {
32 // This macro does nothing but offer an entry point for Rust doc
33 panic!("qproperty! macro called outside #[qobject].");
34}
35
36/// Derive macro that generates a `QModelItem` implementation.
37///
38/// Applying this macro to a struct allows it to be used inside `QVec<T>`
39/// and exposed to QML, where it can be visualized with various views. The
40/// delegates within the view are able to read and write to the struct
41/// through the roles.
42///
43/// ## Roles
44/// - **Named Field Struct:** The generated roles will match the names of the
45/// fileds (e.g., `name`, `age`, …). Fields named `display`, `decoration`,
46/// `edit`, `toolTip`, `statusTip`, or `whatsThis` are recognized as default
47/// roles as used in Qt's default delegates.
48/// - **Tuple Structs:** The generated roles are `"_0"`, `"_1"`, `"_2"`, ...
49///
50/// ## Type requirements
51/// All fields must be convertible to and from `QVariant`.
52///
53/// ## Example
54/// ```rust,ignore
55/// #[derive(QModelItem)]
56/// struct Person {
57/// name: String, // role "name"
58/// age: u32, // role "age"
59/// }
60///
61/// #[derive(QModelItem)]
62/// struct Pair(i32, String); // roles "_0", "_1"
63/// ```
64#[proc_macro_derive(QModelItem)]
65pub fn derive_qmodelitem(input: TokenStream) -> TokenStream {
66 match qt_derive::try_derive_qmodelitem(input) {
67 Ok(ts) => ts,
68 Err(e) => e.to_compile_error().into(),
69 }
70}
71
72/// Includes a file and makes it accessible under the Qt resource system.
73///
74/// The macro uses the include_bytes! macro internally so the file path has to be
75/// given relative to the current file.
76///
77/// An optional prefix can be added as a second macro parameter.
78///
79/// # Examples
80///
81/// ```ignore
82/// fn main() {
83/// include_bytes_qml!("icon.png", "images");
84/// }
85/// ```
86///
87/// This makes the file 'icon.png' that has to be in the same folder as
88/// the file with the macro accessible in QML as 'qrc:/images/icon.png'
89/// or ':/images.icon.png'
90///
91/// ```qml
92/// Image {
93/// source: "qrc:/images/icon.png"
94/// }
95/// ```
96#[proc_macro]
97pub fn include_bytes_qml(input: TokenStream) -> TokenStream {
98 qt_resource::include_bytes_qml(input)
99}