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 defaults() {
157 let c = WsConfig::default();
158 assert_eq!(c.heartbeat_interval, Duration::from_secs(30));
159 assert_eq!(c.broadcast_capacity, 1024);
160 assert_eq!(c.max_connections, 1000);
161 }
162
163 #[test]
164 fn builder_overrides() {
165 let c = WsConfig::builder()
166 .heartbeat_interval(Duration::from_secs(10))
167 .broadcast_capacity(512)
168 .max_connections(10)
169 .build();
170 assert_eq!(c.heartbeat_interval, Duration::from_secs(10));
171 assert_eq!(c.broadcast_capacity, 512);
172 assert_eq!(c.max_connections, 10);
173 }
174
175 #[test]
176 fn builder_default_equals_config_default() {
177 let via_builder = WsConfig::builder().build();
178 assert_eq!(via_builder, WsConfig::default());
179 }
180
181 #[test]
182 fn req_wskit_201_default_allowed_origins_empty_allows_all() {
183 assert!(WsConfig::default().allowed_origins.is_empty());
185 assert!(WsConfig::builder().build().allowed_origins.is_empty());
186 }
187
188 #[test]
189 fn req_wskit_200_builder_sets_allowed_origins() {
190 let c = WsConfig::builder()
191 .allow_origin("https://app.example.com")
192 .allow_origin("https://staging.example.com")
193 .build();
194 assert_eq!(
195 c.allowed_origins,
196 vec![
197 "https://app.example.com".to_string(),
198 "https://staging.example.com".to_string()
199 ]
200 );
201 let c2 = WsConfig::builder()
203 .allow_origin("https://a.dev")
204 .allowed_origins(vec!["https://b.dev".to_string()])
205 .build();
206 assert_eq!(c2.allowed_origins, vec!["https://b.dev".to_string()]);
207 }
208}