nginx_discovery/types/
server.rs1use crate::types::{AccessLog, ErrorLog, ListenDirective, Location};
8use std::path::PathBuf;
9#[derive(Debug, Clone, PartialEq)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub struct Server {
15 pub server_names: Vec<String>,
17
18 pub listen: Vec<ListenDirective>,
20
21 pub root: Option<PathBuf>,
23
24 pub locations: Vec<Location>,
26
27 pub access_logs: Vec<AccessLog>,
29
30 pub error_logs: Vec<ErrorLog>,
32
33 pub index: Vec<String>,
35}
36
37impl Default for Server {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl Server {
44 #[must_use]
46 pub fn new() -> Self {
47 Self {
48 server_names: Vec::new(),
49 listen: Vec::new(),
50 root: None,
51 locations: Vec::new(),
52 access_logs: Vec::new(),
53 error_logs: Vec::new(),
54 index: Vec::new(),
55 }
56 }
57
58 #[must_use]
60 pub fn with_server_name(mut self, name: impl Into<String>) -> Self {
61 self.server_names.push(name.into());
62 self
63 }
64
65 #[must_use]
67 pub fn with_listen(mut self, listen: ListenDirective) -> Self {
68 self.listen.push(listen);
69 self
70 }
71
72 #[must_use]
74 pub fn with_root(mut self, root: impl Into<PathBuf>) -> Self {
75 self.root = Some(root.into());
76 self
77 }
78
79 #[must_use]
81 pub fn has_ssl(&self) -> bool {
82 self.listen.iter().any(|l| l.ssl)
83 }
84
85 #[must_use]
87 pub fn is_default_server(&self) -> bool {
88 self.listen.iter().any(|l| l.default_server)
89 }
90
91 #[must_use]
93 pub fn primary_name(&self) -> Option<&str> {
94 self.server_names.first().map(String::as_str)
95 }
96
97 #[must_use]
99 pub fn with_index(mut self, index: impl Into<String>) -> Self {
100 self.index.push(index.into());
101 self
102 }
103
104 #[must_use]
106 pub fn with_location(mut self, location: Location) -> Self {
107 self.locations.push(location);
108 self
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115 use crate::types::LocationModifier;
116
117 #[test]
118 fn test_server_new() {
119 let server = Server::new();
120 assert!(server.server_names.is_empty());
121 assert!(server.listen.is_empty());
122 assert!(server.root.is_none());
123 assert!(server.locations.is_empty());
124 assert!(server.access_logs.is_empty());
125 assert!(server.error_logs.is_empty());
126 assert!(server.index.is_empty());
127 }
128
129 #[test]
130 fn test_server_default() {
131 let server = Server::default();
132 assert!(server.server_names.is_empty());
133 assert!(server.listen.is_empty());
134 }
135
136 #[test]
137 fn test_with_server_name() {
138 let server = Server::new()
139 .with_server_name("example.com")
140 .with_server_name("www.example.com");
141
142 assert_eq!(server.server_names.len(), 2);
143 assert_eq!(server.server_names[0], "example.com");
144 assert_eq!(server.server_names[1], "www.example.com");
145 }
146
147 #[test]
148 fn test_with_listen() {
149 let listen = ListenDirective::new("0.0.0.0", 80);
150 let server = Server::new().with_listen(listen.clone());
151
152 assert_eq!(server.listen.len(), 1);
153 assert_eq!(server.listen[0].port, 80);
154 assert_eq!(server.listen[0].address, "0.0.0.0");
155 }
156
157 #[test]
158 fn test_with_root() {
159 let server = Server::new().with_root("/var/www/html");
160
161 assert!(server.root.is_some());
162 assert_eq!(server.root.unwrap(), PathBuf::from("/var/www/html"));
163 }
164
165 #[test]
166 fn test_with_index() {
167 let server = Server::new()
168 .with_index("index.html")
169 .with_index("index.php");
170
171 assert_eq!(server.index.len(), 2);
172 assert_eq!(server.index[0], "index.html");
173 assert_eq!(server.index[1], "index.php");
174 }
175
176 #[test]
177 fn test_with_location() {
178 let location = Location::new("/", LocationModifier::None);
179 let server = Server::new().with_location(location);
180
181 assert_eq!(server.locations.len(), 1);
182 assert_eq!(server.locations[0].path, "/");
183 }
184
185 #[test]
186 fn test_has_ssl_true() {
187 let mut listen_ssl = ListenDirective::new("0.0.0.0", 443);
188 listen_ssl.ssl = true;
189 let server = Server::new().with_listen(listen_ssl);
190
191 assert!(server.has_ssl());
192 }
193
194 #[test]
195 fn test_has_ssl_false() {
196 let listen = ListenDirective::new("0.0.0.0", 80);
197 let server = Server::new().with_listen(listen);
198
199 assert!(!server.has_ssl());
200 }
201
202 #[test]
203 fn test_has_ssl_mixed() {
204 let listen_http = ListenDirective::new("0.0.0.0", 80);
205 let mut listen_https = ListenDirective::new("0.0.0.0", 443);
206 listen_https.ssl = true;
207
208 let server = Server::new()
209 .with_listen(listen_http)
210 .with_listen(listen_https);
211
212 assert!(server.has_ssl());
213 }
214
215 #[test]
216 fn test_is_default_server_true() {
217 let mut listen = ListenDirective::new("0.0.0.0", 80);
218 listen.default_server = true;
219 let server = Server::new().with_listen(listen);
220
221 assert!(server.is_default_server());
222 }
223
224 #[test]
225 fn test_is_default_server_false() {
226 let listen = ListenDirective::new("0.0.0.0", 80);
227 let server = Server::new().with_listen(listen);
228
229 assert!(!server.is_default_server());
230 }
231
232 #[test]
233 fn test_primary_name_some() {
234 let server = Server::new()
235 .with_server_name("example.com")
236 .with_server_name("www.example.com");
237
238 assert_eq!(server.primary_name(), Some("example.com"));
239 }
240
241 #[test]
242 fn test_primary_name_none() {
243 let server = Server::new();
244 assert_eq!(server.primary_name(), None);
245 }
246
247 #[test]
248 fn test_builder_pattern_complete() {
249 let mut listen = ListenDirective::new("0.0.0.0", 443);
250 listen.ssl = true;
251 let location = Location::new("/api", LocationModifier::None);
252
253 let server = Server::new()
254 .with_server_name("example.com")
255 .with_listen(listen)
256 .with_root("/var/www")
257 .with_index("index.html")
258 .with_location(location);
259
260 assert_eq!(server.server_names.len(), 1);
261 assert_eq!(server.listen.len(), 1);
262 assert!(server.root.is_some());
263 assert_eq!(server.index.len(), 1);
264 assert_eq!(server.locations.len(), 1);
265 assert!(server.has_ssl());
266 }
267}