Skip to main content

compose_rust/
extensions.rs

1//! Compile-time widget extensions.
2//!
3//! An extension is a pair of source files, one Rust and one Kotlin, built into both sides.
4//! It is not a runtime plugin: a deployed Renderer has no way to load a new widget.
5//!
6//! An application that builds a paired Renderer owns a patched copy of this registry. To add a
7//! widget, update the descriptor and append its wire entries in both macros as needed. Codegen
8//! consumes the resulting closed schema and regenerates `Protocol.gen.kt`. The paired Kotlin
9//! source still has to render the new kind, and each authoring layer declares how it is written:
10//! the Dioxus adapter's element and typed component live in its own `extensions.rs`.
11
12/// Hash input for extension property types, which the flat enum tables cannot express.
13/// Extension widget tags start at 100. Tags 1 to 29 belong to the core vocabulary, and an
14/// extension that sat inside that range would collide with a core widget the next time one
15/// was added. Extension property tags are append-only from 27, which is where the core
16/// property tags stopped when this example was written.
17pub(crate) const SCHEMA_DESCRIPTOR: &str =
18    "extension=LinearProgressIndicator#100(progress:f32#27);";
19
20macro_rules! define_widget_schema_with_extensions {
21    ($define:ident; $schema:ident, $name:ident { $($base:tt)* }) => {
22        $define!($schema, $name {
23            $($base)*
24            // Extension widget tags are append-only.
25            LinearProgressIndicator = 100,
26        });
27    };
28}
29
30macro_rules! define_property_schema_with_extensions {
31    ($define:ident; $schema:ident, $name:ident { $($base:tt)* }) => {
32        $define!($schema, $name {
33            $($base)*
34            // Extension property tags are append-only.
35            Progress = 27,
36        });
37    };
38}
39
40pub(crate) use define_property_schema_with_extensions;
41pub(crate) use define_widget_schema_with_extensions;