straw/rust/README.md
Cobb Hayes 42cb945654 Public-flip audit: scrub audit-ticket prefixes + LAN refs + tighten README
URLs → git.sulkta.com. Audit-ticket prefixes (SPEC §N, audit Track X, vc=N
audit-fix, FIX (audit ...), PORT DEVIATION) stripped from comments — technical
reasoning retained. Crafting-table LAN refs softened to 'Sulkta build host'.
README sheds marketing scaffolding + stale status tables.
2026-05-27 13:29:53 -07:00

56 lines
2.6 KiB
Markdown

# `rust/` — strawcore: Rust YouTube core for Straw
Phase **U-** of the Straw build. Goal: replace the Java NewPipeExtractor
dependency with a Rust core (rustypipe + tokio + reqwest), exposed to the
Kotlin/Compose UI via [UniFFI](https://mozilla.github.io/uniffi-rs/).
Compose UI stays in Kotlin — only the YouTube/Innertube fetching layer
moves to Rust.
## Phases
| Phase | What |
|---|---|
| **U-1** | Toolchain + UniFFI smoke test (`hello_from_rust`) round-tripping through JNA. No real APIs yet. |
| **U-2** | rustypipe search. `SearchViewModel` calls the Rust core. |
| **U-3** | rustypipe streamInfo + streams. `VideoDetailViewModel` + `PlayerViewModel` use it. |
| **U-4** | rustypipe channel + tabs. `ChannelViewModel` + `SubscriptionFeedViewModel`. |
| **U-5** | Rip NewPipeExtractor Java dep. Measure APK + cold-fetch latency before/after. |
| **U-6** *(stretch)* | SponsorBlock + RYD HTTP through reqwest + tokio in the same lib. |
## Build chain
```
Build container (Sulkta uses one; any toolchain matching this layout works)
├── rustup stable (target add: aarch64-linux-android, armv7-linux-androideabi,
│ x86_64-linux-android, i686-linux-android)
├── cargo-ndk (cross-compile helper)
├── android-sdk (ANDROID_HOME, sdkmanager, build-tools, platforms)
└── android-ndk (ANDROID_NDK_HOME, r27c LTS)
Gradle (strawApp/build.gradle.kts)
├── cargoBuild Exec task → cargo ndk -t <abi>... -o jniLibs/ build --release
├── uniffiBindgen Exec task → cargo run --bin uniffi-bindgen ... --library libstrawcore.so
└── source-set wiring generated Kotlin lands in strawApp/src/main/java/uniffi/strawcore/
Runtime (StrawApp.onCreate)
├── System.loadLibrary("strawcore")
└── uniffi.strawcore.initLogging()
```
## Why UniFFI (and not raw JNI / JNA bindings)
- Hand-written JNI: tedious, error-prone, every type change is two files
(Kotlin + Rust) that must stay in sync.
- Raw JNA: better, but you still hand-write the Kotlin side and worry about
string ownership.
- UniFFI: write Rust, annotate with `#[uniffi::export]`, get a Kotlin shim
generated. Strings, structs, enums, Result types, `async` functions all
cross the boundary transparently. The runtime is JNA under the hood.
## When in doubt
- `cargo check -p strawcore --target aarch64-linux-android` — fast iteration.
- `cargo run --bin uniffi-bindgen -- generate ...` — regenerate Kotlin bindings.
- `adb logcat -s strawcore` — Rust `log::info!()` lands here.
- `aapt dump badging strawApp/build/outputs/apk/debug/strawApp-debug.apk`
inspect what ABIs/native-libs the APK carries.