axum_cometd/context/build_router.rs
1use crate::{handlers::*, LongPollingServiceContext};
2use axum::{routing::post, Extension, Router};
3use core::fmt::Debug;
4use std::sync::Arc;
5
6/// A builder to construct `axum::Route` of CometD server.
7#[derive(Debug)]
8pub struct RouterBuilder {
9 subscribe_base_path: &'static str,
10 handshake_base_path: &'static str,
11 connect_base_path: &'static str,
12 disconnect_base_path: &'static str,
13}
14
15impl Default for RouterBuilder {
16 #[inline(always)]
17 fn default() -> Self {
18 Self {
19 subscribe_base_path: "/",
20 handshake_base_path: "",
21 connect_base_path: "",
22 disconnect_base_path: "",
23 }
24 }
25}
26
27impl RouterBuilder {
28 /// Construct a new `RouterBuilder`.
29 #[inline(always)]
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 /// Return a `axum::Router`.
35 ///
36 /// # Example
37 /// ```rust,no_run
38 /// use std::sync::Arc;
39 /// use axum_cometd::RouterBuilder;
40 ///
41 /// # let context = axum_cometd::LongPollingServiceContextBuilder::new().build();
42 /// let app = RouterBuilder::new().build::<()>(Arc::clone(&context));
43 /// ```
44 #[inline(always)]
45 pub fn build<CustomData>(
46 self,
47 context: Arc<LongPollingServiceContext<(), CustomData>>,
48 ) -> Router
49 where
50 CustomData: Send + Sync + 'static,
51 {
52 self.build_with_additional_data(context)
53 .layer(Extension(()))
54 }
55
56 /// Return a `axum::Router`.
57 ///
58 /// # Example
59 /// ```rust,no_run
60 /// use std::sync::Arc;
61 /// use axum::Extension;
62 /// use axum_cometd::RouterBuilder;
63 ///
64 /// # let context = axum_cometd::LongPollingServiceContextBuilder::new().build::<ContextData, ()>();
65 /// #[derive(Clone)]
66 /// struct ContextData {
67 /// server_name: String,
68 /// }
69 ///
70 /// let app = RouterBuilder::new()
71 /// .build_with_additional_data(Arc::clone(&context))
72 /// .layer(Extension(ContextData {
73 /// server_name: std::env::var("SERVER_NAME").unwrap_or_else(|_| "Skalica".to_owned()),
74 /// }));
75 /// ```
76 #[inline]
77 pub fn build_with_additional_data<AdditionalData, CustomData>(
78 self,
79 context: Arc<LongPollingServiceContext<AdditionalData, CustomData>>,
80 ) -> Router
81 where
82 AdditionalData: Clone + Send + Sync + 'static,
83 CustomData: Send + Sync + 'static,
84 {
85 let Self {
86 subscribe_base_path,
87 handshake_base_path,
88 connect_base_path,
89 disconnect_base_path,
90 } = self;
91
92 Router::new()
93 .route(subscribe_base_path, post(subscribe))
94 .route(&format!("{handshake_base_path}/handshake"), post(handshake))
95 .route(&format!("{connect_base_path}/connect"), post(connect))
96 .route(
97 &format!("{disconnect_base_path}/disconnect"),
98 post(disconnect),
99 )
100 .with_state(context)
101 }
102
103 /// Set subscribe base-path for routers.
104 ///
105 /// # Example
106 /// ```rust,no_run
107 /// use std::sync::Arc;
108 /// use axum_cometd::RouterBuilder;
109 ///
110 /// # let context = axum_cometd::LongPollingServiceContextBuilder::new().build();
111 /// let app = RouterBuilder::new()
112 /// // Ex: `/` -> `/bar`
113 /// .subscribe_base_path("/bar")
114 /// .build::<()>(Arc::clone(&context));
115 /// ```
116 #[inline(always)]
117 #[must_use]
118 pub const fn subscribe_base_path(self, path: &'static str) -> Self {
119 Self {
120 subscribe_base_path: path,
121 ..self
122 }
123 }
124
125 /// Set handshake base-path for routers.
126 ///
127 /// # Example
128 /// ```rust,no_run
129 /// use std::sync::Arc;
130 /// use axum_cometd::RouterBuilder;
131 ///
132 /// # let context = axum_cometd::LongPollingServiceContextBuilder::new().build();
133 /// let app = RouterBuilder::new()
134 /// // Ex: `/handshake` -> `/bar/handshake`
135 /// .handshake_base_path("/bar")
136 /// .build::<()>(Arc::clone(&context));
137 /// ```
138 #[inline(always)]
139 #[must_use]
140 pub const fn handshake_base_path(self, path: &'static str) -> Self {
141 Self {
142 handshake_base_path: path,
143 ..self
144 }
145 }
146
147 /// Set connect base-path for routers.
148 ///
149 /// # Example
150 /// ```rust,no_run
151 /// use std::sync::Arc;
152 /// use axum_cometd::RouterBuilder;
153 ///
154 /// # let context = axum_cometd::LongPollingServiceContextBuilder::new().build();
155 /// let app = RouterBuilder::new()
156 /// // Ex: `/connect` -> `/bar/connect`
157 /// .connect_base_path("/bar")
158 /// .build::<()>(Arc::clone(&context));
159 /// ```
160 #[inline(always)]
161 #[must_use]
162 pub const fn connect_base_path(self, path: &'static str) -> Self {
163 Self {
164 connect_base_path: path,
165 ..self
166 }
167 }
168
169 /// Set disconnect base-path for routers.
170 ///
171 /// # Example
172 /// ```rust,no_run
173 /// use std::sync::Arc;
174 /// use axum_cometd::RouterBuilder;
175 ///
176 /// # let context = axum_cometd::LongPollingServiceContextBuilder::new().build();
177 /// let app = RouterBuilder::new()
178 /// // Ex: `/disconnect` -> `/bar/disconnect`
179 /// .disconnect_base_path("/bar")
180 /// .build::<()>(Arc::clone(&context));
181 /// ```
182 #[inline(always)]
183 #[must_use]
184 pub const fn disconnect_base_path(self, path: &'static str) -> Self {
185 Self {
186 disconnect_base_path: path,
187 ..self
188 }
189 }
190}