Skip to main content

compose_rust/
lib.rs

1#![deny(unsafe_op_in_unsafe_fn)]
2
3// `#[composable]` expands into paths that start at `::compose_rust`, so that an application
4// that depends on this crate alone can use it. This makes the same paths resolve inside the
5// crate, where its own composables are written.
6extern crate self as compose_rust;
7
8pub mod animation;
9pub mod asset;
10pub mod boundary;
11/// Generated JNI shims. Compiled only for Android, where the Host is a cdylib that the
12/// Kotlin Activity loads.
13#[cfg(target_os = "android")]
14#[path = "boundary_jni.gen.rs"]
15mod boundary_jni;
16/// Generated wasm shims. Compiled only for the browser, where the page owns the loop and
17/// the Renderer's module owns the one linear memory both halves read.
18#[cfg(target_family = "wasm")]
19#[path = "boundary_wasm.gen.rs"]
20mod boundary_wasm;
21pub mod brush;
22pub mod code;
23/// The rule the code colours of the two systems without a code editor scheme are derived
24/// by. Only the tests run it: the values themselves are literals in the token tables.
25#[cfg(test)]
26mod code_colours;
27pub mod contrast;
28#[cfg(target_family = "wasm")]
29#[doc(hidden)]
30pub use boundary_wasm::web_start as __web_start;
31#[doc(hidden)]
32pub mod codegen;
33pub mod design;
34pub mod drawing;
35mod extensions;
36pub mod fonts;
37pub mod highlight;
38pub mod input;
39pub mod measure;
40pub mod message;
41pub mod notification;
42pub mod palette;
43pub mod protocol;
44pub mod runtime;
45pub mod schema;
46pub mod spans;
47pub mod theme;
48pub mod tokens;
49pub mod ui;
50pub mod window;
51pub mod windows;
52mod writer;
53pub mod zoom;
54
55pub use animation::{
56    Animated, AnimationMoment, AnimationSpec, GraphicsLayer, animate_color_as_state,
57    animate_float_as_state, animate_offset_as_state, control_animation, reduced_motion,
58    start_animation, transition,
59};
60pub use asset::asset;
61pub use boundary::{
62    Host, LaunchBuilder, MutationBatch, RendererApi, RuntimeFactory, demo_theme, demo_theme_for,
63    install_renderer_api, launch_runtime, request_frame_from_worker,
64};
65pub use brush::{Brush, Stop, brush, release_brush};
66pub use code::{
67    CodeChange, CodeHover, CodeRange, Decoration, Decorations, EditRejected, Fold, FoldChange,
68    Folds, GutterDecoration, GutterDecorations, Position, SaveRequest, SelectionChange, SyntaxSpan,
69    SyntaxSpans, VisibleRange,
70};
71pub use design::design_system;
72pub use drawing::{DrawCommand, DrawList, DrawListBuilder};
73pub use fonts::{FontRef, FontRefs, FontStack};
74pub use input::{FileDrop, KeyEvent, PointerEvent, PointerKinds, RangeRequest, pointer_button};
75pub use message::{Message, show_message};
76pub use notification::{
77    Notification, NotificationActivation, NotificationSender, notification_permission,
78    request_notification_permission, withdraw_notification,
79};
80pub use palette::{Palette, PaletteViolation};
81pub use runtime::{Batch, ComposeHost, Recomposer, Runtime, application, composable, launch};
82pub use schema::{
83    Alignment, Arrangement, AssetKind, ButtonKind, ButtonVariant, Chrome, Color, ColorRole,
84    ColorScheme, DecorationKind, DesignSystem, EventPayload, GenericFamily, GutterDecorationKind,
85    HoverPhase, IconRole, Key, LoopMode, MaterialRole, MessageDuration, Modifier, MotionRole,
86    NotificationImportance, NotificationPermission, NotificationPresentation, OverflowWrap, Paint,
87    PropertyKind, RevealAlign, SCHEMA_HASH, Selection, Severity, ShapeRole, SpaceRole, TextAlign,
88    TextOverflow, Theme, TileMode, TypeRole, WidgetKind, WindowHeightClass, WindowSizeClass,
89    WordBreak,
90};
91pub use schema::{
92    AnimatedProperty, Animation, AnimationControl, AnimationEventKind, AnimationEvents,
93    ColorInterpolation, FillMode, Keyframe, KeyframeValue, PlayState, PlaybackDirection,
94    ReducedMotion, StepPosition, Timing, TransformFunction, TransformFunctionKind,
95};
96pub use schema::{Cursor, PointerKind, PointerType, UserSelect, WheelDeltaMode};
97pub use theme::ThemeHandle;
98pub use ui::{ScrollState, remember_scroll_state};
99pub use window::{NodeSize, WindowSize, node_size, window_size};
100pub use windows::{
101    DragFromPointer, LastWindowClosed, WindowDragEvent, WindowDragOver, WindowDragOverKind,
102    WindowDragPhase, WindowEvent, WindowFrame, WindowHandle, WindowMode, WindowRequest,
103    current_window,
104};
105pub use zoom::{Zoom, ZoomHandle, zoom};
106
107/// Declares the entry point an iOS application starts at.
108///
109/// iOS is the one platform where the application is the library: the renderer is a
110/// Kotlin/Native archive and the two are linked into a single executable, so there is no
111/// Activity to load anything and no page to fetch anything. What there is instead is a
112/// `main`, and a `main` in an application bundle has to be C, so this exports the launch
113/// under a name that C can call.
114///
115/// ```ignore
116/// compose_rust::ios_main!(launch);
117/// ```
118///
119/// The export exists only in a build for iOS. Anywhere else nothing calls it, and an
120/// unconditional export would collide with the same name in every other application
121/// linked into one binary, which is what a benchmark that drives several of them does.
122#[macro_export]
123macro_rules! ios_main {
124    ($launch:path) => {
125        #[cfg(target_os = "ios")]
126        #[unsafe(no_mangle)]
127        pub extern "C" fn compose_rust_ios_main() -> i32 {
128            $launch();
129            0
130        }
131    };
132}
133
134/// Declares the Android entry point for an application whose root is a composable.
135///
136/// Android has no `main`: the Kotlin Activity owns the process and the frame loop, so the
137/// root is registered from `JNI_OnLoad`, which the generated shims reach through the
138/// symbol this defines.
139///
140/// ```ignore
141/// compose_rust::android_application!(app);
142/// ```
143///
144/// The export exists only in a build for Android, for the reason [`ios_main!`] gives.
145#[macro_export]
146macro_rules! android_application {
147    ($content:path) => {
148        $crate::android_application!($crate::LaunchBuilder::new(), $content);
149    };
150    ($builder:expr, $content:path) => {
151        #[cfg(target_os = "android")]
152        #[unsafe(no_mangle)]
153        pub extern "C" fn compose_rust_android_main() {
154            let _ = $builder
155                .with_mode($crate::LoopMode::Platform)
156                .try_launch($content);
157        }
158    };
159}
160
161/// Declares the browser entry point for an application whose root is a composable.
162///
163/// A page has no library loader and no `main` of its own: the Renderer's module owns the
164/// loop and calls this once both wasm modules exist. The export is defined where the root
165/// is because a browser refuses to instantiate a module with an import nobody supplies.
166///
167/// ```ignore
168/// compose_rust::web_application!(app);
169/// ```
170#[macro_export]
171macro_rules! web_application {
172    ($content:path) => {
173        $crate::web_application!($crate::LaunchBuilder::new(), $content);
174    };
175    ($builder:expr, $content:path) => {
176        #[cfg(target_family = "wasm")]
177        #[unsafe(no_mangle)]
178        pub extern "C" fn compose_rust_host_web_start() -> u32 {
179            $crate::__web_start($builder, $crate::runtime::recomposer_for($content))
180        }
181
182        /// Off the web nothing calls this, but the builder and the root are still type
183        /// checked. Not exported, so it collides with no other application in a binary.
184        #[cfg(not(target_family = "wasm"))]
185        #[allow(dead_code)]
186        fn __compose_rust_web_start_unused() -> u32 {
187            let _: fn() = $content;
188            let _ = $builder;
189            0
190        }
191    };
192}