NewPipeExtractor (Java) → strawcore (Rust) migration begins. Phase U:
- U-1: Rust toolchain + UniFFI smoke test
- U-2: rustypipe search via uniffi suspend fun, SearchViewModel swapped
What landed:
- rust/strawcore — UniFFI-exported Rust crate using proc-macros.
Builds for arm64-v8a + armeabi-v7a + x86 + x86_64 via cargo-ndk.
Tokio multi-thread runtime singleton drives rustypipe's async API.
- strawApp/build.gradle.kts — cargoBuildHost + cargoBuild + uniffiBindgen
Gradle Exec tasks chained into the Android build. Generated Kotlin
bindings land in src/main/java/uniffi/strawcore/ (gitignored).
- SearchViewModel.kt — calls uniffi.strawcore.search(query) directly.
NewPipeExtractor still in deps for VideoDetail/Player/Channel paths;
those move to Rust in U-3 / U-4.
- Build chain quirks beat:
* cargo absolute path in Exec tasks (PATH wasn't propagating)
* uniffi-bindgen needs UNSTRIPPED host .so — separate cargoBuildHost
builds a debug-profile host lib to read metadata from
* rustypipe rustls-tls-webpki-roots avoids the openssl-sys
cross-compile tarpit
* rquickjs-sys 'bindgen' feature opted in (no prebuilt Android
bindings ship; crafting-table has libclang 14)
- crafting-table runtime install (until Dockerfile catches up):
rustup + 4 Android targets + cargo-ndk + NDK r27c. Persists in
/caches/cargo + /caches/android-sdk via the volume mount.
APK size: 22MB (U-1) → 37MB (U-2). libstrawcore.so 3-5MB per ABI carries
rustypipe + reqwest + tokio + rustls + rquickjs. NewPipeExtractor still
in for now (still drives detail + player + channel + feed), so the
Java half is doubled up. U-5 removes it.
56 lines
2.6 KiB
Markdown
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
|
|
|
|
```
|
|
crafting-table
|
|
├── 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 at /caches/android-sdk/ndk/...)
|
|
|
|
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.
|