allframe_core/router/
config.rs1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct RouterConfig {
11 pub server: ServerConfig,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct ServerConfig {
18 pub protocols: Vec<String>,
20
21 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub rest: Option<RestConfig>,
24
25 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub graphql: Option<GraphQLConfig>,
28
29 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub grpc: Option<GrpcConfig>,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct RestConfig {
37 #[serde(default = "default_rest_port")]
39 pub port: u16,
40
41 #[serde(default = "default_rest_prefix")]
43 pub path_prefix: String,
44}
45
46fn default_rest_port() -> u16 {
47 8080
48}
49
50fn default_rest_prefix() -> String {
51 "/api/v1".to_string()
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct GraphQLConfig {
57 #[serde(default = "default_graphql_port")]
59 pub port: u16,
60
61 #[serde(default = "default_graphql_path")]
63 pub path: String,
64
65 #[serde(default)]
67 pub playground: bool,
68}
69
70fn default_graphql_port() -> u16 {
71 8081
72}
73
74fn default_graphql_path() -> String {
75 "/graphql".to_string()
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct GrpcConfig {
81 #[serde(default = "default_grpc_port")]
83 pub port: u16,
84
85 #[serde(default)]
87 pub reflection: bool,
88}
89
90fn default_grpc_port() -> u16 {
91 9090
92}
93
94impl RouterConfig {
95 pub fn from_toml(toml: &str) -> Result<Self, String> {
97 toml::from_str(toml).map_err(|e| format!("Failed to parse config: {}", e))
98 }
99
100 pub fn from_file(path: &str) -> Result<Self, String> {
102 let contents =
103 std::fs::read_to_string(path).map_err(|e| format!("Failed to read file: {}", e))?;
104 Self::from_toml(&contents)
105 }
106
107 pub fn protocols(&self) -> &[String] {
109 &self.server.protocols
110 }
111
112 pub fn has_protocol(&self, protocol: &str) -> bool {
114 self.server.protocols.contains(&protocol.to_string())
115 }
116
117 pub fn rest(&self) -> Option<&RestConfig> {
119 self.server.rest.as_ref()
120 }
121
122 pub fn graphql(&self) -> Option<&GraphQLConfig> {
124 self.server.graphql.as_ref()
125 }
126
127 pub fn grpc(&self) -> Option<&GrpcConfig> {
129 self.server.grpc.as_ref()
130 }
131}
132
133impl RestConfig {
134 pub fn port(&self) -> u16 {
136 self.port
137 }
138
139 pub fn path_prefix(&self) -> &str {
141 &self.path_prefix
142 }
143}
144
145impl GraphQLConfig {
146 pub fn port(&self) -> u16 {
148 self.port
149 }
150
151 pub fn path(&self) -> &str {
153 &self.path
154 }
155
156 pub fn playground(&self) -> bool {
158 self.playground
159 }
160}
161
162impl GrpcConfig {
163 pub fn port(&self) -> u16 {
165 self.port
166 }
167
168 pub fn reflection(&self) -> bool {
170 self.reflection
171 }
172}
173
174#[cfg(test)]
175mod tests {
176 use super::*;
177
178 #[test]
179 fn test_parse_basic_config() {
180 let toml = r#"
181 [server]
182 protocols = ["rest", "graphql"]
183 "#;
184
185 let config = RouterConfig::from_toml(toml).unwrap();
186 assert_eq!(config.protocols().len(), 2);
187 assert!(config.has_protocol("rest"));
188 assert!(config.has_protocol("graphql"));
189 assert!(!config.has_protocol("grpc"));
190 }
191
192 #[test]
193 fn test_parse_full_config() {
194 let toml = r#"
195 [server]
196 protocols = ["rest", "graphql", "grpc"]
197
198 [server.rest]
199 port = 8080
200 path_prefix = "/api/v1"
201
202 [server.graphql]
203 port = 8081
204 path = "/graphql"
205 playground = true
206
207 [server.grpc]
208 port = 9090
209 reflection = true
210 "#;
211
212 let config = RouterConfig::from_toml(toml).unwrap();
213
214 assert_eq!(config.protocols().len(), 3);
216 assert!(config.has_protocol("rest"));
217 assert!(config.has_protocol("graphql"));
218 assert!(config.has_protocol("grpc"));
219
220 let rest = config.rest().unwrap();
222 assert_eq!(rest.port(), 8080);
223 assert_eq!(rest.path_prefix(), "/api/v1");
224
225 let graphql = config.graphql().unwrap();
227 assert_eq!(graphql.port(), 8081);
228 assert_eq!(graphql.path(), "/graphql");
229 assert!(graphql.playground());
230
231 let grpc = config.grpc().unwrap();
233 assert_eq!(grpc.port(), 9090);
234 assert!(grpc.reflection());
235 }
236
237 #[test]
238 fn test_parse_minimal_config() {
239 let toml = r#"
240 [server]
241 protocols = ["rest"]
242 "#;
243
244 let config = RouterConfig::from_toml(toml).unwrap();
245 assert_eq!(config.protocols().len(), 1);
246 assert!(config.has_protocol("rest"));
247 assert!(config.rest().is_none()); }
249
250 #[test]
251 fn test_default_values() {
252 let toml = r#"
253 [server]
254 protocols = ["rest", "graphql", "grpc"]
255
256 [server.rest]
257 [server.graphql]
258 [server.grpc]
259 "#;
260
261 let config = RouterConfig::from_toml(toml).unwrap();
262
263 let rest = config.rest().unwrap();
265 assert_eq!(rest.port(), 8080);
266 assert_eq!(rest.path_prefix(), "/api/v1");
267
268 let graphql = config.graphql().unwrap();
270 assert_eq!(graphql.port(), 8081);
271 assert_eq!(graphql.path(), "/graphql");
272 assert!(!graphql.playground()); let grpc = config.grpc().unwrap();
276 assert_eq!(grpc.port(), 9090);
277 assert!(!grpc.reflection()); }
279}