Skip to main content

moq_native/
lib.rs

1//! Helper library for native MoQ applications.
2//!
3//! Establishes MoQ connections over:
4//! - WebTransport (HTTP/3)
5//! - Raw QUIC (with ALPN negotiation)
6//! - WebSocket (fallback via [web-transport-ws](https://crates.io/crates/web-transport-ws))
7//! - Plain TCP via the `tcp://` scheme (qmux, no TLS; requires `tcp` feature)
8//! - Unix domain socket via the `unix://` scheme (qmux, peer-credential aware; requires `uds` feature, unix-only)
9//! - Iroh P2P (requires `iroh` feature)
10//!
11//! See [`Client`] for connecting to relays and [`Server`] for accepting connections.
12
13#![warn(missing_docs)]
14
15pub mod bind;
16mod client;
17mod connect;
18mod crypto;
19mod error;
20#[cfg(any(feature = "quinn", feature = "noq", feature = "quiche", feature = "tcp"))]
21pub mod failover;
22#[cfg(feature = "jemalloc")]
23pub mod jemalloc;
24mod log;
25#[cfg(feature = "noq")]
26pub mod noq;
27pub mod quic;
28#[cfg(feature = "quinn")]
29pub mod quinn;
30mod reconnect;
31mod server;
32#[cfg(feature = "tcp")]
33pub mod tcp;
34pub mod tls;
35#[cfg(all(feature = "uds", unix))]
36pub mod unix;
37mod util;
38#[cfg(feature = "watch")]
39pub mod watch;
40#[cfg(feature = "websocket")]
41pub mod websocket;
42
43// Enumerated rather than globbed, so the root surface is a deliberate list and a
44// new `pub` item in these modules doesn't silently join it.
45pub use client::{Client, ClientConfig};
46pub use connect::ConnectError;
47pub use error::{Error, Result};
48pub use log::Log;
49pub use reconnect::{Backoff, ConnectionStatsReader, Reconnect, Status};
50pub use server::{Request, Server, ServerConfig, Transport};
51
52/// Spawn the session's protocol driver on the current tokio runtime, handing back
53/// the session it drives.
54///
55/// The driver holds no session clone, so the session still closes when the caller
56/// drops their last [`moq_net::Session`] handle, which in turn lets the driver
57/// task finish.
58pub(crate) fn spawn_session((session, driver): (moq_net::Session, moq_net::Driver)) -> moq_net::Session {
59	tokio::spawn(driver);
60	session
61}
62
63// Re-export these crates.
64pub use moq_net;
65pub use rustls;
66
67/// Re-exported because [`watch::FileWatcher`] surfaces `notify::Result`/`notify::Error`
68/// in its API; a major `notify` bump is therefore a breaking change for this crate.
69#[cfg(feature = "watch")]
70pub use notify;
71
72/// Re-exported because [`tls::init_android`] takes a `jni::Env` handle; a major
73/// `jni` bump is therefore a breaking change for this crate.
74#[cfg(target_os = "android")]
75pub use jni;
76
77#[cfg(feature = "quiche")]
78pub mod quiche;
79
80#[cfg(feature = "iroh")]
81pub mod iroh;
82
83/// The QUIC backend to use for connections.
84#[derive(Clone, Debug, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
85#[serde(rename_all = "lowercase")]
86#[non_exhaustive]
87pub enum QuicBackend {
88	/// [web-transport-quinn](https://crates.io/crates/web-transport-quinn)
89	#[cfg(feature = "quinn")]
90	Quinn,
91
92	/// [web-transport-quiche](https://crates.io/crates/web-transport-quiche)
93	#[cfg(feature = "quiche")]
94	Quiche,
95
96	/// [web-transport-noq](https://crates.io/crates/web-transport-noq)
97	#[cfg(feature = "noq")]
98	Noq,
99}
100
101fn default_quic_backend() -> QuicBackend {
102	#[cfg(feature = "quinn")]
103	{
104		QuicBackend::Quinn
105	}
106	#[cfg(all(feature = "noq", not(feature = "quinn")))]
107	{
108		QuicBackend::Noq
109	}
110	#[cfg(all(feature = "quiche", not(feature = "quinn"), not(feature = "noq")))]
111	{
112		QuicBackend::Quiche
113	}
114	#[cfg(all(not(feature = "quiche"), not(feature = "quinn"), not(feature = "noq")))]
115	panic!("no QUIC backend compiled; enable noq, quinn, or quiche feature");
116}
117
118#[cfg(test)]
119mod tests {
120	#[cfg(feature = "quinn")]
121	#[test]
122	fn quinn_is_the_default_backend() {
123		assert!(matches!(super::default_quic_backend(), super::QuicBackend::Quinn));
124	}
125}