-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCargo.toml
More file actions
225 lines (220 loc) · 12.4 KB
/
Copy pathCargo.toml
File metadata and controls
225 lines (220 loc) · 12.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
[workspace]
resolver = "3"
members = ["crates/core", "crates/image", "crates/tui", "crates/gallery", "crates/a2ui", "crates/slint", "crates/slint-gallery", "crates/egui", "crates/egui-gallery", "crates/bevy", "crates/bevy-gallery", "crates/iced", "crates/iced-gallery", "crates/dioxus", "crates/dioxus-gallery"]
# The GPUI backend (`crates/gpui` + `crates/gpui-gallery`) is intentionally
# **excluded** from this workspace: `gpui 0.2.2` pins `cocoa = "=0.26.0"` (an
# exact, macOS-only transitive dep), while `dioxus-desktop` (pulled into this
# workspace's lockfile via the aggregator crate's optional `a2ui-dioxus` dep)
# needs `cocoa ^0.26.1`. No single `cocoa` version satisfies both, so the two
# cannot share a Cargo.lock. The gpui crates therefore live in their own
# self-contained workspace (each with its own `[workspace]` table) and build
# independently — see `crates/gpui/Cargo.toml` / `crates/gpui-gallery/Cargo.toml`
# and the build recipe in the comment block below.
exclude = ["crates/gpui", "crates/gpui-gallery"]
# `cargo build` / `cargo run` with no `-p` compile only the ratatui stack. Every
# GUI backend (slint / egui / bevy / iced / dioxus) is opt-in — each pulls a
# sizeable GUI toolchain, so build one explicitly, e.g.
# `cargo build -p a2ui-bevy --features backend`.
# The GPUI backend is built separately (it lives in its own workspace; see the
# `exclude` note above): `cargo build --manifest-path crates/gpui-gallery/Cargo.toml`.
#
# KNOWN LIMITATION — never build/lint/test the GUI backends together with a bare
# `--workspace` / `--all-features`: `iced 0.14` (→ wgpu 27 → naga 27) and
# `bevy 0.19` (→ bevy_shader → naga_oil 0.22) both resolve `codespan-reporting
# 0.12.0` with conflicting feature needs — naga_oil *requires* its `termcolor`
# feature, while naga 27.0.3 only compiles with it *off*. Cargo unifies them
# onto one codespan 0.12.0 build with `termcolor` ON, and naga 27 then fails
# (`String: WriteColor not satisfied`). Each backend builds cleanly on its own
# (`-p a2ui-<backend> --features backend`); only resolving bevy + iced in the
# same invocation triggers it. The `just clippy` / `just test` recipes below
# iterate the default stack + each backend separately to avoid this.
default-members = ["crates/core", "crates/tui", "crates/gallery", "crates/a2ui"]
[workspace.package]
version = "0.3.1"
edition = "2024"
authors = ["Liangdi <wu@liangdi.me>"]
license = "MIT"
repository = "https://github.com/Liangdi/a2ui"
[workspace.dependencies]
# External crates — versions centralized here, consumed via `{ workspace = true }`.
ratatui = "0.30.2"
crossterm = "0.29"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "2"
chrono = "0.4"
uuid = { version = "1", features = ["v4"] }
regex = "1"
unicode-width = "0.2"
ratatui-image = "11"
image = "0.25"
# SVG rasterizer (resvg bundles usvg + tiny-skia, re-exported from `resvg`).
# Used by the `a2ui-tui` Image component to render `data:image/svg+xml` URIs and
# local `.svg` files — a single dep is enough (resvg re-exports the other two).
resvg = "0.47"
# data-URI payload decoding for the Image component: `;base64` bodies and the
# URL-percent-encoded `data:image/svg+xml,...` form.
base64 = "0.22"
percent-encoding = "2.3"
# User-level config file for the gallery (e.g. the persisted image-protocol
# choice). `dirs` resolves the platform config dir; `toml` is the editable
# format. Both already resolve transitively, so this just promotes them.
dirs = "6"
toml = "1.1"
# Embed the A2UI specification tree into the binary at compile time so the
# gallery is self-contained and distributable (no on-disk spec dir needed).
include_dir = "0.7"
rodio = "0.22"
# Slint runtime for the `a2ui-slint` backend. `default-features = false` + `std`
# give the core types (SharedString, Model, the `slint!` macro) without committing
# to a windowing backend — consumers pick a renderer (e.g. `renderer-femtovg`,
# `renderer-software`) when launching.
slint = { version = "1.17", default-features = false, features = ["std", "compat-1-2"] }
# Build-time compiler: turns `.slint` files into Rust modules via `slint_build`
# in `build.rs`. (The inline `slint::slint!` macro rejects recursive components,
# so the backend compiles real `.slint` files instead.)
slint-build = { version = "1.17" }
# egui immediate-mode GUI runtime for the `a2ui-egui` backend. Unlike Slint,
# egui is native-recursive and pure-Rust (winit + glow, no system GUI libs), so
# the backend needs no `build.rs`. `egui` is kept default-less (core types only);
# `eframe` carries its defaults (glow renderer + the winit X11/Wayland backends
# + default fonts) so it links a working windowing backend on Linux. The
# windowing deps are pulled in by the `backend` feature in `a2ui-egui`.
# Pinned to 0.33 (latest stable line on crates.io as of 2026-06).
egui = { version = "0.35", default-features = false }
eframe = "0.35"
# Bevy ECS + UI runtime for the `a2ui-bevy` backend. The fourth renderer,
# targeting game/embedded runtimes. Bevy UI is ECS retained-mode, so (unlike
# egui's per-frame rebuild) the backend keeps a stable entity tree and
# diff/patches it each frame. `default-features = false` + the explicit feature
# set below pull only the UI stack (layout, text, windowing, picking, input
# focus, the experimental `bevy_ui_widgets` headless widgets, and the wgpu UI
# render path) — skipping the heavy 3D/audio/subset that `bevy/default` would
# drag in. `ui_bevy_render` is what actually wires the wgpu render backend for
# UI nodes; the windowing backend comes from `bevy_winit`.
bevy = { version = "0.19", default-features = false, features = [
"bevy_ui",
"bevy_text",
"bevy_winit",
"bevy_input_focus",
"bevy_picking",
# UI picking backend: without it, UI nodes don't emit `Pointer<Click>` /
# drag events, so `bevy_ui_widgets` Button `Activate` and our sample-list
# click observer never fire (the `picking` feature pulls this in by default,
# but we set `default-features = false`).
"ui_picking",
"ui_bevy_render",
"bevy_ui_widgets",
# Bundle the built-in FiraMono-subset.ttf as the default font. `default_font`
# is on in `bevy/default`, but we set `default-features = false`, so without
# this `TextFont::default()` resolves to no font and **no text renders** —
# the sample list (and every label) would be blank.
"default_font",
# Windowing backends for Linux. `bevy_winit` ships neither by default, so
# winit fails to compile on a headless feature set — opt into both so the
# gallery runs under either display server. (egui's eframe enables these
# via its own defaults; here we name them explicitly.)
"wayland",
"x11",
] }
# Iced Elm-architecture GUI runtime for the `a2ui-iced` backend. The fifth
# renderer. Iced is the cleanest A2UI mapping of the bunch: it is Elm
# (immutable `view(&state)` + `update(&mut state, msg)`), so — unlike egui's
# immediate mode (which needs an `EditBuffers` bridge) or bevy's retained ECS
# (which needs a reconciler) — interactive widgets read straight from the data
# model in `view` and write back through a `Message` in `update`. No state
# bridge, no diffing. `default-features = false` + the explicit set below keep
# the build lean: `wgpu` is the GPU renderer (mirrors the bevy backend),
# `tiny-skia` is the software fallback, `thread-pool` is the native futures
# executor (iced requires one of thread-pool/tokio/smol), and `x11`/`wayland`
# are the Linux display-server backends. Pinned to 0.14 (latest stable line on
# crates.io as of 2026-06).
iced = { version = "0.14", default-features = false, features = [
"wgpu",
"tiny-skia",
"thread-pool",
"x11",
"wayland",
"image",
] }
# Lightweight sync HTTP client (rustls TLS) used by the iced backend to fetch
# remote `Image` component URLs (the gallery samples all reference `https://`
# images). Sync (no async runtime) so a fetch runs as a single blocking call
# inside an Iced `Task::perform` future on the `thread-pool` executor — no
# tokio/smol mixed in. ureq 3.x: TLS via the `rustls` feature; per-request
# `.timeout()` moved to the `Agent` config (see each backend's fetch helper).
ureq = { version = "3", features = ["rustls"] }
# Dioxus reactive RSX GUI runtime for the `a2ui-dioxus` backend. The sixth
# renderer — and architecturally the most distinct of the bunch. Dioxus is a
# *reactive-signals* framework whose desktop target renders to a system WebView
# (WebKitGTK on Linux, WebView2 on Windows, WKWebView on macOS), so — unlike the
# native-widget backends (Iced/egui/Bevy) — the A2UI tree maps to **HTML +
# CSS**, and the bespoke dark theme is a stylesheet rather than a style-fn
# palette. Recursion is idiomatic here: a single `A2uiNode` component renders
# itself per node (Dioxus supports recursive components natively, unlike Slint's
# bounded-depth codegen), and the `MessageProcessor` lives in a `Signal` at the
# root so any write automatically re-renders the subscribers — no Iced-style
# `Message` enum, no egui-style `EditBuffers` bridge. `default-features = false`
# drops the devtools/fullstack/web stack; the explicit set keeps only what the
# desktop backend needs: `desktop` (the wry/tao launcher), `launch`
# (`LaunchBuilder`), `macro` (`rsx!`/`#[component]`), `html` (the element +
# event DSL), `signals` (`Signal`/`use_signal`), `hooks` (`use_context`).
# Pinned to 0.7 (latest stable line on crates.io as of 2026-06).
dioxus = { version = "0.7", default-features = false, features = [
"desktop",
"launch",
"macro",
"html",
"signals",
"hooks",
] }
# NOTE: `gpui` / `gpui-component` / `gpui-component-assets` are NOT declared
# here. The GPUI backend lives in its own workspace (`crates/gpui`,
# `crates/gpui-gallery`, excluded above) and inlines those versions directly —
# see those manifests. (gpui-component 0.5.1 depends on `gpui = ^0.2.2`; all
# pinned to the latest crates.io line as of 2026-07.)
# Internal crates — path dependencies shared across the workspace. Each carries
# a `version` (the workspace package version) so `cargo publish` can resolve them
# against crates.io (the `path` is stripped on publish). Consumers use
# `{ workspace = true }` and inherit both.
a2ui-base = { path = "crates/core", version = "0.3.1" }
# Shared image source resolution (http / data: / file://) + raster decode.
# A leaf utility crate consumed by the TUI + every GUI backend so the image
# fetch/decode logic (and `data:` / `file://` support) is defined exactly once.
a2ui-image = { path = "crates/image", version = "0.3.1" }
a2ui-tui = { path = "crates/tui", version = "0.3.1" }
a2ui-gallery = { path = "crates/gallery", version = "0.3.1" }
a2ui-slint = { path = "crates/slint", version = "0.3.1" }
a2ui-egui = { path = "crates/egui", version = "0.3.1" }
a2ui-bevy = { path = "crates/bevy", version = "0.3.1" }
a2ui-iced = { path = "crates/iced", version = "0.3.1" }
a2ui-dioxus = { path = "crates/dioxus", version = "0.3.1" }
# --- Release profile: optimize for binary size --------------------------------
# The gallery embeds the full spec tree, so we trim the distributed binary.
# `cargo build --release` applies these. Trade slower compile for a smaller,
# self-contained executable.
[profile.release]
# "z" optimizes purely for size (smaller than "s", which keeps some speed).
opt-level = "z"
# Whole-program link-time optimization: eliminates dead code across crates.
lto = true
# One codegen unit → more inlining/dead-code elimination (slower compile).
codegen-units = 1
# Abort instead of unwind on panic: drops unwinding machinery. NOTE: panics no
# longer unwind, so Drop destructors don't run during a panic.
panic = "abort"
# Strip debug symbols from the binary.
strip = true
# --- Workspace lints ----------------------------------------------------------
# Centralized lint policy: every crate inherits this via `[lints] workspace = true`
# in its own manifest. `clippy::all` is the default group and is already at zero
# warnings — declaring it here enforces that and propagates it to all crates, so
# the cleanliness can't silently regress in one backend. `dbg_macro` catches
# stray `dbg!()` calls left in committed code. (`print_stdout` / `print_stderr`
# and the `cargo` group were tried and dropped: this workspace is full of CLIs,
# examples, and a gallery binary that legitimately print, so those lints were
# pure noise; `cargo` flags missing `keywords`/`categories`/`readme`, a separate
# publish-discoverability task.)
[workspace.lints.clippy]
all = { level = "warn", priority = -1 }
dbg_macro = "warn"