Skip to main content

doido_cable/
lib.rs

1pub mod cable;
2pub mod channel;
3pub mod config;
4pub mod connection;
5#[cfg(feature = "cable-db")]
6pub mod db_pubsub;
7pub mod heartbeat;
8pub mod protocol;
9pub mod pubsub;
10#[cfg(feature = "cable-redis")]
11pub mod redis_pubsub;
12pub mod server;
13pub mod streams;
14
15pub use cable::Cable;
16pub use channel::{Channel, ChannelContext, ChannelName};
17pub use config::{build_configured_pubsub, CableConfig};
18pub use connection::CableConnection;
19pub use server::{handle_socket, route as cable_route, ws_handler, ChannelRegistry};
20
21/// Build the pub/sub backend selected by the `cable` section of
22/// `config/<env>.yml` (in-memory when absent), connecting the database for the
23/// `db` backend. Pair with [`cable!`] to mount the endpoint:
24///
25/// ```ignore
26/// let pubsub = doido_cable::pubsub_from_config().await?;
27/// let app = doido_cable::cable!(pubsub, [ChatChannel]);
28/// ```
29pub async fn pubsub_from_config() -> doido_core::Result<std::sync::Arc<dyn PubSub>> {
30    build_configured_pubsub(&config::load()).await
31}
32// The `#[channel]` attribute macro. It lives in the macro namespace, so it
33// coexists with the `channel` module (type namespace); `channel_macro` is kept
34// as an alias for callers that prefer the unambiguous name.
35#[cfg(feature = "cable-db")]
36pub use db_pubsub::DbPubSub;
37pub use doido_cable_macros::channel;
38pub use doido_cable_macros::channel as channel_macro;
39pub use protocol::{CableFrame, ServerFrame, ServerMessage};
40pub use pubsub::{MemoryPubSub, PubSub};
41#[cfg(feature = "cable-redis")]
42pub use redis_pubsub::RedisPubSub;
43
44/// Build an axum `Router` mounting the cable endpoint (`/cable`) for the given
45/// channels over a pub/sub backend (Rails' `mount ActionCable.server`):
46///
47/// ```ignore
48/// let app = doido_cable::cable!(pubsub, [ChatChannel, NotificationsChannel]);
49/// // With a configured heartbeat interval:
50/// let app = doido_cable::cable!(pubsub, [ChatChannel], heartbeat = cfg.ping_interval);
51/// ```
52#[macro_export]
53macro_rules! cable {
54    ($pubsub:expr, [ $($channel:expr),* $(,)? ]) => {{
55        let mut __registry = $crate::server::ChannelRegistry::new($pubsub);
56        $( __registry.register_channel($channel); )*
57        $crate::server::route(::std::sync::Arc::new(__registry))
58    }};
59    ($pubsub:expr, [ $($channel:expr),* $(,)? ], heartbeat = $heartbeat:expr) => {{
60        let mut __registry =
61            $crate::server::ChannelRegistry::new($pubsub).with_heartbeat($heartbeat);
62        $( __registry.register_channel($channel); )*
63        $crate::server::route(::std::sync::Arc::new(__registry))
64    }};
65}