Skip to main content

rustapi_core/app/
config.rs

1use super::types::RustApi;
2use crate::middleware::{LayerStack, MiddlewareLayer};
3
4/// Configuration builder for RustAPI with auto-routes
5pub struct RustApiConfig {
6    docs_path: Option<String>,
7    docs_enabled: bool,
8    api_title: String,
9    api_version: String,
10    api_description: Option<String>,
11    body_limit: Option<usize>,
12    layers: LayerStack,
13}
14
15impl Default for RustApiConfig {
16    fn default() -> Self {
17        Self::new()
18    }
19}
20
21impl RustApiConfig {
22    pub fn new() -> Self {
23        Self {
24            docs_path: Some("/docs".to_string()),
25            docs_enabled: true,
26            api_title: "RustAPI".to_string(),
27            api_version: "1.0.0".to_string(),
28            api_description: None,
29            body_limit: None,
30            layers: LayerStack::new(),
31        }
32    }
33
34    /// Set the docs path (default: "/docs")
35    pub fn docs_path(mut self, path: impl Into<String>) -> Self {
36        self.docs_path = Some(path.into());
37        self
38    }
39
40    /// Enable or disable docs (default: true)
41    pub fn docs_enabled(mut self, enabled: bool) -> Self {
42        self.docs_enabled = enabled;
43        self
44    }
45
46    /// Set OpenAPI info
47    pub fn openapi_info(
48        mut self,
49        title: impl Into<String>,
50        version: impl Into<String>,
51        description: Option<impl Into<String>>,
52    ) -> Self {
53        self.api_title = title.into();
54        self.api_version = version.into();
55        self.api_description = description.map(|d| d.into());
56        self
57    }
58
59    /// Set body size limit
60    pub fn body_limit(mut self, limit: usize) -> Self {
61        self.body_limit = Some(limit);
62        self
63    }
64
65    /// Add a middleware layer
66    pub fn layer<L>(mut self, layer: L) -> Self
67    where
68        L: MiddlewareLayer,
69    {
70        self.layers.push(Box::new(layer));
71        self
72    }
73
74    /// Build the RustApi instance
75    pub fn build(self) -> RustApi {
76        let mut app = RustApi::new().mount_auto_routes_grouped();
77
78        // Apply configuration
79        if let Some(limit) = self.body_limit {
80            app = app.body_limit(limit);
81        }
82
83        app = app.openapi_info(
84            &self.api_title,
85            &self.api_version,
86            self.api_description.as_deref(),
87        );
88
89        #[cfg(feature = "swagger-ui")]
90        if self.docs_enabled {
91            if let Some(path) = self.docs_path {
92                app = app.docs(&path);
93            }
94        }
95
96        // Apply layers
97        // Note: layers are applied in reverse order in RustApi::layer logic (pushing to vec)
98        app.layers.extend(self.layers);
99
100        app
101    }
102
103    /// Build and run the server
104    pub async fn run(
105        self,
106        addr: impl AsRef<str>,
107    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
108        self.build().run(addr.as_ref()).await
109    }
110}