1use std::time::Duration;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct WsConfig {
29 pub heartbeat_interval: Duration,
31 pub broadcast_capacity: usize,
33 pub max_connections: usize,
35 pub allowed_origins: Vec<String>,
50}
51
52impl Default for WsConfig {
53 fn default() -> Self {
54 Self {
55 heartbeat_interval: Duration::from_secs(30),
56 broadcast_capacity: 1024,
57 max_connections: 1000,
58 allowed_origins: Vec::new(),
59 }
60 }
61}
62
63impl WsConfig {
64 pub fn new() -> Self {
66 Self::default()
67 }
68
69 pub fn builder() -> WsConfigBuilder {
71 WsConfigBuilder::default()
72 }
73}
74
75#[derive(Debug, Clone)]
77pub struct WsConfigBuilder {
78 heartbeat_interval: Duration,
79 broadcast_capacity: usize,
80 max_connections: usize,
81 allowed_origins: Vec<String>,
82}
83
84impl Default for WsConfigBuilder {
85 fn default() -> Self {
86 let d = WsConfig::default();
87 Self {
88 heartbeat_interval: d.heartbeat_interval,
89 broadcast_capacity: d.broadcast_capacity,
90 max_connections: d.max_connections,
91 allowed_origins: d.allowed_origins,
92 }
93 }
94}
95
96impl WsConfigBuilder {
97 pub fn heartbeat_interval(mut self, v: Duration) -> Self {
99 self.heartbeat_interval = v;
100 self
101 }
102
103 pub fn broadcast_capacity(mut self, v: usize) -> Self {
105 self.broadcast_capacity = v;
106 self
107 }
108
109 pub fn max_connections(mut self, v: usize) -> Self {
111 self.max_connections = v;
112 self
113 }
114
115 pub fn allowed_origins(mut self, origins: Vec<String>) -> Self {
119 self.allowed_origins = origins;
120 self
121 }
122
123 pub fn allow_origin(mut self, origin: impl Into<String>) -> Self {
127 self.allowed_origins.push(origin.into());
128 self
129 }
130
131 pub fn build(self) -> WsConfig {
133 WsConfig {
134 heartbeat_interval: self.heartbeat_interval,
135 broadcast_capacity: self.broadcast_capacity,
136 max_connections: self.max_connections,
137 allowed_origins: self.allowed_origins,
138 }
139 }
140}
141
142#[allow(
146 clippy::unwrap_used,
147 clippy::expect_used,
148 clippy::indexing_slicing,
149 clippy::panic
150)]
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn new_equals_default() {
157 assert_eq!(WsConfig::new(), WsConfig::default());
158 }
159
160 #[test]
161 fn defaults() {
162 let c = WsConfig::default();
163 assert_eq!(c.heartbeat_interval, Duration::from_secs(30));
164 assert_eq!(c.broadcast_capacity, 1024);
165 assert_eq!(c.max_connections, 1000);
166 }
167
168 #[test]
169 fn builder_overrides() {
170 let c = WsConfig::builder()
171 .heartbeat_interval(Duration::from_secs(10))
172 .broadcast_capacity(512)
173 .max_connections(10)
174 .build();
175 assert_eq!(c.heartbeat_interval, Duration::from_secs(10));
176 assert_eq!(c.broadcast_capacity, 512);
177 assert_eq!(c.max_connections, 10);
178 }
179
180 #[test]
181 fn builder_default_equals_config_default() {
182 let via_builder = WsConfig::builder().build();
183 assert_eq!(via_builder, WsConfig::default());
184 }
185
186 #[test]
187 fn req_wskit_201_default_allowed_origins_empty_allows_all() {
188 assert!(WsConfig::default().allowed_origins.is_empty());
190 assert!(WsConfig::builder().build().allowed_origins.is_empty());
191 }
192
193 #[test]
194 fn req_wskit_200_builder_sets_allowed_origins() {
195 let c = WsConfig::builder()
196 .allow_origin("https://app.example.com")
197 .allow_origin("https://staging.example.com")
198 .build();
199 assert_eq!(
200 c.allowed_origins,
201 vec![
202 "https://app.example.com".to_string(),
203 "https://staging.example.com".to_string()
204 ]
205 );
206 let c2 = WsConfig::builder()
208 .allow_origin("https://a.dev")
209 .allowed_origins(vec!["https://b.dev".to_string()])
210 .build();
211 assert_eq!(c2.allowed_origins, vec!["https://b.dev".to_string()]);
212 }
213}