Skip to content

Improve Avalonia-to-Rust mapping with hierarchy traits, rsx!, reactive signals, AXAML transpiler, and view-model scanner - #13

Merged
Marc-André Moreau (mamoreau-devolutions) merged 3 commits into
masterfrom
copilot/avalonia-rust-mapping-improvements
Oct 21, 2026
Merged

Marc-André Moreau (mamoreau-devolutions) merged 3 commits into
masterfrom
copilot/avalonia-rust-mapping-improvements

Conversation

@mamoreau-devolutions

Copy link
Copy Markdown
Contributor

Summary

Improves the Avalonia-to-Rust authoring surface across both code-first UI and managed AXAML + Rust view-model interop while keeping all published COM IIDs and vtable layouts unchanged:

  • Hierarchy-Aware Wrappers (Upcast<Target>, Downcast<Target>, Deref):
    • Marks generated control wrappers #[repr(transparent)] and ComPtr<T> #[repr(C)].
    • Emits Deref<Target = ParentType>, static Upcast<Ancestor> / AsRef<Ancestor>, and safe runtime Downcast<Sub> (is::<T>(), cast::<T>()) across the control hierarchy, plus object_id(), same_object(), and NonOwningRef<T>.
  • Ergonomic Property Conversions & Inline Attached Properties:
    • Adds tuple/scalar/array From conversions for Thickness, CornerRadius, Size, Point, Vector, Rect, PixelPoint, Color (including Color::parse_hex), Brush, and Paint.
    • Emits content_text / header_text helpers and inline attached-property builders (.grid_row(...), .grid_column(...), .dock_panel_dock(...), .canvas_left(...), .tool_tip_tip(...), etc.) on controls.
  • Declarative El<T> Builders, rsx! Macro & Reactive Control Flow (Show / For):
    • Adds deferred El<T> descriptors (Control::el(), AppScope::mount_view, mount_into_*, ControlSlot) and the rsx! declarative macro supporting attached properties (Grid.row: 1), ref: node_ref, class: "...", string/expression children, and if/for blocks.
    • Adds Show::when / Show::when_else and keyed For::each (KeyedListReconciler, .children_for(...), .items_for(...)) that reuse realized controls and update per-item Signal<T> handles in place.
  • Fine-Grained Scoped Reactivity, Context Injection, Safe Command & Async Resource<T>:
    • Adds Copy arena-backed Signal<T>, Memo<T>, Effect, NodeRef<T>, TwoWay<T>, ReactiveScope (with automatic subtree effect disposal), provide_context<T> / use_context<T>, Command::with_can_execute, Resource<T> (AppScope::create_resource), theme_variant_signal, resource_signal, theme_brush, and data_template_reactive container pooling.
    • Implements IntoValue<T> and IntoProp<T, Marker> so El<T> setters accept static values, signals, memos, closures, and signal.two_way().
  • Compile-Time AXAML-to-Rust Transpiler (compile_axaml / --compile-axaml):
    • Adds rustolonia-bindgen --compile-axaml <input.axaml> <output.rs> to compile .axaml markup into typed El<T> builders, <ViewName>Refs, <ViewName>Bindings, and <ViewName>Handlers.
  • Declarative View-Model Macros & Rust Source Scanner (--scan-rust):
    • Adds reactive_view_model!, prop!, when_any!, and ViewModelRustScanner (Avalonia.ViewModelProjection.Tool --scan-rust) supporting #[view_model], #[view_model_enum], #[prop], #[derived], #[collection], and #[command].

Validation

  • cargo test --manifest-path .\rust\Cargo.toml -p rustolonia-bindgen --locked
  • cargo test --manifest-path .\rust\Cargo.toml -p rustolonia --locked
  • cargo check --manifest-path .\rust\Cargo.toml -p rustolonia --examples --locked
  • dotnet build .\projection\Avalonia.ViewModelProjection.Tool\Avalonia.ViewModelProjection.Tool.csproj -c Release
  • pwsh .\rust\tests\test-build-app.ps1

…s, and view-model scanner

- Add #[repr(transparent)] control wrappers, Deref inheritance, and Upcast<Ancestor>
- Add ergonomic tuple/scalar/hex From conversions, content_text/header_text helpers, and inline attached-property builders
- Add deferred El<T> view builders, rsx! macro, and reactive DataTemplate container pooling
- Add AppScope fine-grained Signal<T>, Memo<T>, Effect, NodeRef<T>, and IntoProp<T, Marker> with two-way bindings
- Add reactive_view_model! / prop! macros and ViewModelRustScanner (--scan-rust)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
… scoped reactivity

- Add Downcast<Target> (is/cast), object_id, same_object, and NonOwningRef<T>
- Add Show::when/when_else, keyed For::each / KeyedListReconciler, ControlSlot, and mount_into_*
- Add AppScope::theme_variant_signal, resource_signal, and theme_brush
- Extend reactive_view_model! with derived properties, can_execute predicates, and when_any!
- Add compile-time AXAML-to-Rust transpiler (compile_axaml / --compile-axaml) supporting controls, attached properties, x:Name NodeRefs, TwoWay/StringFormat bindings, events, and DataTemplates
- Add hierarchical ReactiveScope, provide_context/use_context, safe reactive Command, and async Resource<T>
- Add declarative_counter example and integration tests

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…d attribute scanning

- Replace embedded include_str! in non-test compile_axaml with compile_axaml_from_json so cargo package -p rustolonia-bindgen compiles from its standalone package tarball
- Allow quoted string values containing parentheses in ViewModelRustScanner attribute regexes

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) merged commit 6f28e39 into master Oct 21, 2026
10 checks passed
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) deleted the copilot/avalonia-rust-mapping-improvements branch October 21, 2026 11:55
Marc-André Moreau (mamoreau-devolutions) added a commit that referenced this pull request Oct 26, 2026
Version bump for the next release, generated with
`rust/prepare-release.ps1 -Version 12.1.1` (no hand edits).

- `rustolonia`, `rustolonia-sys`, `rustolonia-bindgen` → 12.1.1 (plus
the exact `rustolonia-sys` pin)
- `rust/release-manifest.json` `rustoloniaVersion` and
`build/SharedVersion.props` `<Version>` → 12.1.1
- `rust/rustolonia-sys/host-checksums.txt` cleared (refilled from the
12.1.1 build in the next step)
- `Cargo.lock` refreshed

Includes everything since v12.1.0: #12, #13, #14.

After merge, per `rust/PRODUCTIZATION.md#releasing`:
1. Dispatch **Release** from master with `phase=build`,
`version=12.1.1`.
2. Run `rust/prepare-release.ps1 -Checksums -SumsFile <SHA256SUMS>` from
that run, commit to master, push tag `v12.1.1` on that commit.
3. Dispatch `phase=publish` with `build_run_id` and `version=12.1.1`.

The `templates/*/Cargo.toml` still reference `tag = "v12.1.0"`
intentionally; they can move to `v12.1.1` once the tag exists.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant