Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Shared Rust task board

One Rust task board runs as a native CLI, a browser app, a WASI module, and an Android NativeActivity. Every output loads the same board and asset files, applies the same commands, and prints the same replies.

bazel build //examples/shared-rust/... @shared_consumer//...
bazel test //examples/shared-rust/... @shared_consumer//...

Layout

Crate or targetRole
tasks_modelTask and board parsing, title and asset checks.
tasks_coreBoard commands, summaries, and asset digests through the pinned adler2 2.0.1 crate.
tasksNative and WASI CLI: tasks [--asset=PATH]... BOARD [COMMAND]....
shared_taskswasm-bindgen interface (WebBoard, asset_report, core_version, build_profile).
tasks_ffi, tasks_interfaceC interface (ffi/tasks.h) over the same core.
tasks_activity, tasks_apkAndroid NativeActivity and APK.
assets/board.txt, assets/notes.txtResources every output loads.

Commands are add TITLE, done ID, reopen ID, attach ID ASSET, and remove ID. Replies are ok:<event> or err:<kind>.

The CLI exits 0 on success, 1 when a command is rejected, and 2 for a usage error, an unreadable or invalid board, or a missing asset.

Native

bazel run //examples/shared-rust:tasks -- \
  --asset=$PWD/examples/shared-rust/assets/notes.txt \
  $PWD/examples/shared-rust/assets/board.txt "add Ship it" "done 2"
bazel test //examples/shared-rust:native_test //examples/shared-rust:interface_test

native_test copies the binary and assets to a scratch directory and checks output, exit codes, and error text. interface_test drives the C interface.

Browser

bazel run //examples/shared-rust:serve
bazel test //examples/shared-rust:asset_test //examples/shared-rust:browser_test

browser_test serves the relocated release app in Firefox 157.0. It checks the build profile is release, the rendered tasks, summary, asset digest, and load error, then applies commands through the input and button.

WASI

bazel test //examples/shared-rust:wasi_test \
  //examples/shared-rust:wasi_error_test \
  //examples/shared-rust:wasi_capability_test

tasks_wasi is tasks built for wasm32-wasip1 and run under Wasmtime 49.0.2. wasi_error_test expects exit 1 for a rejected command. wasi_capability_test expects exit 2 and err:unreadable: /board/board.txt when the board is not preopened.

Android

export ANDROID_HOME=$HOME/Android/Sdk ANDROID_NDK_REVISION=27.2.12479018
NDK=--extra_toolchains=@android_ndk_toolchain//:ndk_cc_toolchain_device,@android_ndk_toolchain//:ndk_cc_toolchain_emulator
bazel test $NDK --test_env=ANDROID_HOME \
  //examples/shared-rust:inspect_apk_test \
  //examples/shared-rust:inspect_consumer_apk_test
bazel run $NDK //examples/shared-rust:install
bazel run $NDK //examples/shared-rust:start
bazel run $NDK //examples/shared-rust:log

The inspect tests check the package, SDK floor, label, launch activity, byte-identical assets, exported symbols per ABI, no extra ABIs, and the signature. The activity logs under the DxSharedTasks tag: lifecycle=create through lifecycle=destroy, board=loaded tasks=4 or board=invalid, the summary or summary none, the asset report, and input=touch|key <reply> after a tap or key press.

Tools: NDK 27.2.12479018, build-tools 34.0.0, platform-tools 37.0.0, emulator 37.2.12.0, system image android-34;default;x86_64.

Release

bazel test //examples/shared-rust:release_test

tasks_release, tasks_wasi_release, and app_release build with -c opt. release_test relocates the native binary and WASI module and expects identical output plus build=release. It also runs the WASI module with no preopen and expects err:unreadable: /board/board.txt with exit code 2.

Deploy

dx deploy //examples/shared-rust:tasks_deploy
dx deploy --apply //examples/shared-rust:tasks_deploy
bazel test //examples/shared-rust:tasks_deploy_verify

tasks_deploy is an archive_deploy of tasks. The first command builds it and publishes nothing. --apply checks the tarball against its checksum and copies tasks_deploy.tar.gz and tasks_deploy.tar.gz.sha256 into the workspace root, or into the directory given after --:

archive_deploy: released tasks (profile: release)
  tarball:  /path/to/rules_dx/tasks_deploy.tar.gz
  checksum: /path/to/rules_dx/tasks_deploy.tar.gz.sha256

tasks_deploy_verify checks that the tarball holds tasks and matches the checksum.

Independent consumer

@shared_consumer is a separate workspace that owns its HTML, board, notes, Android resources, permissions, features, rustc flags, and WASI runtime wrapper. It reuses tasks_core, shared_tasks, tasks_activity, and the public toolchains with no SDK or linker setup of its own.

bazel test @shared_consumer//... \
  //examples/shared-rust:consumer_browser_test \
  //examples/shared-rust:consumer_native_test

Offline and errors

bazel fetch //examples/shared-rust/... @shared_consumer//...
bazel test //examples/shared-rust/... @shared_consumer//... \
  --repository_disable_download

Tests tagged block-network run without network. With an empty repository cache, --repository_disable_download fails with download is disabled. missing_interface_test expects a web app without its bindgen interface to fail with requires bindgen to provide RustWasmBindgenInfo. missing_asset_test and bad_asset_path_test cover asset errors.

Pending

  • Custom toolchain override in the consumer: it overrides features, rustc flags, and the WASI runtime wrapper only.
  • Automated offline check: the fetch and --repository_disable_download commands above are not run by any test.
  • Emulator run: needs KVM. Without it the emulator boot loops.
  • Physical arm64 device run.
  • Multi-ABI install on a device.
  • Apple simulator and device outputs.

Debugger integration and game-engine portability are not supported.