Skip to content

Commit 1546ceb

Browse files
committed
Enable set_ws_client and set_http_client injectable interfaces
1 parent e296159 commit 1546ceb

8 files changed

Lines changed: 38 additions & 1 deletion

File tree

.github/workflows/tests.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,10 @@ jobs:
170170
shell: bash
171171
run: |
172172
cargo test --verbose --target ${{ matrix.target }} -p livekit-net --features native-tokio
173-
cargo test --verbose --target ${{ matrix.target }} -p livekit-api --features signal-client-tokio
173+
cargo test --verbose --target ${{ matrix.target }} -p livekit-api --features signal-client-tokio
174+
175+
- name: Build livekit-net uniffi feature (foreign transport bindings)
176+
shell: bash
177+
run: |
178+
cargo build --verbose --target ${{ matrix.target }} -p livekit-net --features uniffi
179+
cargo build --verbose --target ${{ matrix.target }} -p livekit-net --features uniffi,native-tokio

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

livekit-net/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ repository.workspace = true
99
[features]
1010
default = []
1111

12+
# UniFFI bindings: exposes the transport seam across the FFI so a host can
13+
# implement WsClient/HttpClient and register it. Orthogonal to the native
14+
# backends — enable alongside a native-* backend for a host-overridable
15+
# transport that falls back to native.
16+
uniffi = ["dep:uniffi"]
17+
1218
# Native backend bundles — each pairs the net libraries with a runtime.
1319
native-tokio = ["__native", "__native-tokio", "tokio"]
1420
native-async = ["__native", "__native-async", "async"]
@@ -50,6 +56,13 @@ __native-async = ["dep:async-tungstenite", "dep:isahc", "dep:tokio", "dep:future
5056
[dependencies]
5157
async-trait = "0.1"
5258

59+
# Optional: scaffolding for the `uniffi` feature. `scaffolding-ffi-buffer-fns`
60+
# matches livekit-datatrack/livekit-uniffi so the ABI is consistent when these
61+
# crates are combined into one cdylib. No runtime feature: the exported traits
62+
# are `with_foreign` (host-driven futures) and the exported setters are sync, so
63+
# the crate stays runtime-agnostic.
64+
uniffi = { workspace = true, features = ["scaffolding-ffi-buffer-fns"], optional = true }
65+
5366
# Direct path dep (not workspace inheritance) so default-features = false is
5467
# honored: cargo ignores a member's default-features override on an inherited dep,
5568
# which would drag in livekit-runtime's default `tokio` and trip its one-runtime

livekit-net/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ pub use types::{Header, HttpResponse, TransportError};
2525

2626
use std::sync::{Arc, OnceLock};
2727

28+
#[cfg(feature = "uniffi")]
29+
uniffi::setup_scaffolding!();
30+
2831
/// Render a URL for logging with secrets stripped: userinfo (`user:password@`)
2932
/// and the query string (which can carry an access token). Keeps scheme, host,
3033
/// port, and path.
@@ -45,12 +48,14 @@ static HTTP: OnceLock<Arc<dyn HttpClient>> = OnceLock::new();
4548
///
4649
/// Independent of [`set_http_client`]: a consumer that only needs HTTP (e.g. a
4750
/// token source) can register that alone, and vice versa.
51+
#[cfg_attr(feature = "uniffi", uniffi::export)]
4852
pub fn set_ws_client(c: Arc<dyn WsClient>) {
4953
let _ = WS.set(c);
5054
}
5155

5256
/// Register the process-wide HTTP client. Call once at startup, before the first
5357
/// request. A later call is ignored (first registration wins).
58+
#[cfg_attr(feature = "uniffi", uniffi::export)]
5459
pub fn set_http_client(c: Arc<dyn HttpClient>) {
5560
let _ = HTTP.set(c);
5661
}

livekit-net/src/transport.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use std::sync::Arc;
1717

1818
/// A single open WebSocket connection. Control frames (ping/pong, close handshake)
1919
/// are the implementation's own responsibility; only binary application frames cross here.
20+
#[cfg_attr(feature = "uniffi", uniffi::export(with_foreign))]
2021
#[async_trait::async_trait]
2122
pub trait WsConnection: Send + Sync + 'static {
2223
/// Send one binary application frame.
@@ -31,12 +32,14 @@ pub trait WsConnection: Send + Sync + 'static {
3132
///
3233
/// A record wrapper, not a bare `Arc<dyn WsConnection>`: uniffi 0.31 cannot
3334
/// lift a trait object returned from an async `with_foreign` method.
35+
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
3436
pub struct WsConnectResult {
3537
pub connection: Arc<dyn WsConnection>,
3638
}
3739

3840
/// A host- or Rust-provided WebSocket transport. Opens the LiveKit signalling
3941
/// WebSocket; knows nothing about LiveKit/protobuf.
42+
#[cfg_attr(feature = "uniffi", uniffi::export(with_foreign))]
4043
#[async_trait::async_trait]
4144
pub trait WsClient: Send + Sync {
4245
/// Open a WebSocket. `url` is the full ws(s):// URL including query string.
@@ -51,6 +54,7 @@ pub trait WsClient: Send + Sync {
5154
}
5255

5356
/// The HTTP method for an [`HttpClient::request`].
57+
#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
5458
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5559
pub enum HttpMethod {
5660
Get,
@@ -64,6 +68,7 @@ pub enum HttpMethod {
6468
/// Implementors provide the single [`request`](HttpClient::request) primitive;
6569
/// [`HttpClientExt`] layers `get`/`post` on top, so adding verbs never widens the
6670
/// implementation (or, for foreign impls, the FFI) surface.
71+
#[cfg_attr(feature = "uniffi", uniffi::export(with_foreign))]
6772
#[async_trait::async_trait]
6873
pub trait HttpClient: Send + Sync {
6974
/// Perform one HTTP request, sending `body` if present.

livekit-net/src/types.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
use std::fmt;
1616

1717
/// A single HTTP/WebSocket request header.
18+
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
1819
#[derive(Debug, Clone)]
1920
pub struct Header {
2021
pub name: String,
2122
pub value: String,
2223
}
2324

2425
/// The result of an HTTP request performed by the transport.
26+
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
2527
#[derive(Debug, Clone)]
2628
pub struct HttpResponse {
2729
pub status: u16,
@@ -31,6 +33,7 @@ pub struct HttpResponse {
3133
}
3234

3335
/// Errors a transport implementation may return. Mapped onto `SignalError` by the caller.
36+
#[cfg_attr(feature = "uniffi", derive(uniffi::Error))]
3437
#[derive(Debug, Clone)]
3538
pub enum TransportError {
3639
Timeout,

livekit-uniffi/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ publish = false
1515
livekit-protocol = { workspace = true }
1616
livekit-api = { workspace = true, default-features = false, features = ["access-token"] }
1717
livekit-datatrack = { workspace = true, features = ["uniffi"] }
18+
livekit-net = { workspace = true, features = ["uniffi"] }
1819
uniffi = { workspace = true, features = ["scaffolding-ffi-buffer-fns", "tokio"] }
1920
log = { workspace = true }
2021
tokio = { workspace = true, features = ["sync", "rt-multi-thread"] }

livekit-uniffi/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ pub mod common;
3030
/// Global async runtime.
3131
pub mod runtime;
3232

33+
extern crate livekit_net;
34+
3335
uniffi::setup_scaffolding!();

0 commit comments

Comments
 (0)