shape_wire/transport/
factory.rs1use std::sync::Arc;
7
8use super::Transport;
9use super::tcp::TcpTransport;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum TransportKind {
14 Tcp,
15 #[cfg(feature = "quic")]
16 Quic,
17}
18
19#[cfg(feature = "quic")]
20#[derive(Debug, Clone)]
21pub struct QuicFactoryConfig {
22 pub server_name: String,
23 pub root_certs_der: Vec<Vec<u8>>,
24 pub connect_timeout: Option<std::time::Duration>,
25}
26
27#[cfg(feature = "quic")]
28fn quic_config_cell() -> &'static std::sync::RwLock<Option<QuicFactoryConfig>> {
29 static CELL: std::sync::OnceLock<std::sync::RwLock<Option<QuicFactoryConfig>>> =
30 std::sync::OnceLock::new();
31 CELL.get_or_init(|| std::sync::RwLock::new(None))
32}
33
34#[cfg(feature = "quic")]
36pub fn set_quic_config(config: QuicFactoryConfig) {
37 if let Ok(mut guard) = quic_config_cell().write() {
38 *guard = Some(config);
39 }
40}
41
42#[cfg(feature = "quic")]
44pub fn clear_quic_config() {
45 if let Ok(mut guard) = quic_config_cell().write() {
46 *guard = None;
47 }
48}
49
50#[cfg(feature = "quic")]
52pub fn get_quic_config() -> Option<QuicFactoryConfig> {
53 quic_config_cell()
54 .read()
55 .ok()
56 .and_then(|guard| guard.clone())
57}
58
59pub fn create_transport(kind: TransportKind) -> Result<Arc<dyn Transport>, String> {
61 match kind {
62 TransportKind::Tcp => Ok(Arc::new(TcpTransport::default())),
63 #[cfg(feature = "quic")]
64 TransportKind::Quic => {
65 let cfg = get_quic_config().ok_or_else(|| {
66 "transport.quic(): QUIC transport is not configured. \
67Call shape_vm::configure_quic_transport(server_name, root_certs_der, connect_timeout) \
68before requesting a QUIC transport."
69 .to_string()
70 })?;
71
72 let mut quic =
73 super::quic::QuicTransport::with_trust_anchors(cfg.root_certs_der, cfg.server_name)
74 .map_err(|e| format!("transport.quic(): QUIC init: {}", e))?;
75 if let Some(timeout) = cfg.connect_timeout {
76 quic.connect_timeout = timeout;
77 }
78 Ok(Arc::new(quic))
79 }
80 }
81}
82
83pub trait WireTransportProvider: Send + Sync {
88 fn create_transport(&self, kind: TransportKind) -> Result<Arc<dyn Transport>, String>;
89}
90
91#[derive(Debug, Default, Clone, Copy)]
93pub struct ShapeWireProvider;
94
95impl WireTransportProvider for ShapeWireProvider {
96 fn create_transport(&self, kind: TransportKind) -> Result<Arc<dyn Transport>, String> {
97 create_transport(kind)
98 }
99}