elif_openapi/
config.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4/// Configuration for OpenAPI specification generation
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct OpenApiConfig {
7    /// OpenAPI specification version (should be "3.0.3")
8    pub openapi_version: String,
9
10    /// API information
11    pub info: ApiInfo,
12
13    /// Server configurations
14    pub servers: Vec<ServerConfig>,
15
16    /// Global security schemes
17    pub security_schemes: HashMap<String, SecurityScheme>,
18
19    /// Global tags for grouping operations
20    pub tags: Vec<TagConfig>,
21
22    /// External documentation
23    pub external_docs: Option<ExternalDocs>,
24
25    /// Whether to include example values in schemas
26    pub include_examples: bool,
27
28    /// Whether to generate nullable fields for Option<T>
29    pub nullable_optional: bool,
30
31    /// Custom schema mappings for specific types
32    pub custom_schemas: HashMap<String, String>,
33
34    /// Export settings
35    pub export: ExportConfig,
36}
37
38/// API information section
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct ApiInfo {
41    /// API title
42    pub title: String,
43
44    /// API description
45    pub description: Option<String>,
46
47    /// API version
48    pub version: String,
49
50    /// Terms of service URL
51    pub terms_of_service: Option<String>,
52
53    /// Contact information
54    pub contact: Option<Contact>,
55
56    /// License information
57    pub license: Option<License>,
58}
59
60/// Contact information
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct Contact {
63    pub name: Option<String>,
64    pub url: Option<String>,
65    pub email: Option<String>,
66}
67
68/// License information
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct License {
71    pub name: String,
72    pub url: Option<String>,
73}
74
75/// Server configuration
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct ServerConfig {
78    pub url: String,
79    pub description: Option<String>,
80    pub variables: Option<HashMap<String, ServerVariable>>,
81}
82
83/// Server variable for parameterized server URLs
84#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct ServerVariable {
86    pub default: String,
87    pub description: Option<String>,
88    pub r#enum: Option<Vec<String>>,
89}
90
91/// Security scheme configuration
92#[derive(Debug, Clone, Serialize, Deserialize)]
93#[serde(tag = "type", rename_all = "camelCase")]
94pub enum SecurityScheme {
95    #[serde(rename = "http")]
96    Http {
97        scheme: String,
98        bearer_format: Option<String>,
99    },
100    #[serde(rename = "apiKey")]
101    ApiKey { name: String, r#in: String },
102    #[serde(rename = "oauth2")]
103    OAuth2 { flows: OAuth2Flows },
104    #[serde(rename = "openIdConnect")]
105    OpenIdConnect { open_id_connect_url: String },
106}
107
108/// OAuth2 flows configuration
109#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct OAuth2Flows {
111    pub authorization_code: Option<OAuth2Flow>,
112    pub implicit: Option<OAuth2Flow>,
113    pub password: Option<OAuth2Flow>,
114    pub client_credentials: Option<OAuth2Flow>,
115}
116
117/// Individual OAuth2 flow
118#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct OAuth2Flow {
120    pub authorization_url: Option<String>,
121    pub token_url: Option<String>,
122    pub refresh_url: Option<String>,
123    pub scopes: HashMap<String, String>,
124}
125
126/// Tag configuration for grouping operations
127#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct TagConfig {
129    pub name: String,
130    pub description: Option<String>,
131    pub external_docs: Option<ExternalDocs>,
132}
133
134/// External documentation reference
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct ExternalDocs {
137    pub url: String,
138    pub description: Option<String>,
139}
140
141/// Export configuration
142#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct ExportConfig {
144    /// Output formats to generate
145    pub formats: Vec<ExportFormat>,
146
147    /// Whether to validate generated specifications
148    pub validate: bool,
149
150    /// Pretty print JSON output
151    pub pretty_print: bool,
152}
153
154/// Available export formats
155#[derive(Debug, Clone, Serialize, Deserialize)]
156#[serde(rename_all = "lowercase")]
157pub enum ExportFormat {
158    Json,
159    Yaml,
160    Postman,
161    Insomnia,
162}
163
164impl Default for OpenApiConfig {
165    fn default() -> Self {
166        Self {
167            openapi_version: "3.0.3".to_string(),
168            info: ApiInfo {
169                title: "API Documentation".to_string(),
170                description: Some("Auto-generated API documentation".to_string()),
171                version: "1.0.0".to_string(),
172                terms_of_service: None,
173                contact: None,
174                license: Some(License {
175                    name: "MIT".to_string(),
176                    url: Some("https://opensource.org/licenses/MIT".to_string()),
177                }),
178            },
179            servers: vec![ServerConfig {
180                url: "http://localhost:3000".to_string(),
181                description: Some("Development server".to_string()),
182                variables: None,
183            }],
184            security_schemes: {
185                let mut schemes = HashMap::new();
186                schemes.insert(
187                    "bearerAuth".to_string(),
188                    SecurityScheme::Http {
189                        scheme: "bearer".to_string(),
190                        bearer_format: Some("JWT".to_string()),
191                    },
192                );
193                schemes
194            },
195            tags: Vec::new(),
196            external_docs: None,
197            include_examples: true,
198            nullable_optional: true,
199            custom_schemas: HashMap::new(),
200            export: ExportConfig {
201                formats: vec![ExportFormat::Json, ExportFormat::Yaml],
202                validate: true,
203                pretty_print: true,
204            },
205        }
206    }
207}
208
209impl OpenApiConfig {
210    /// Create a new configuration with custom API info
211    pub fn new(title: &str, version: &str) -> Self {
212        let mut config = Self::default();
213        config.info.title = title.to_string();
214        config.info.version = version.to_string();
215        config
216    }
217
218    /// Add a server configuration
219    pub fn add_server(mut self, url: &str, description: Option<&str>) -> Self {
220        self.servers.push(ServerConfig {
221            url: url.to_string(),
222            description: description.map(|s| s.to_string()),
223            variables: None,
224        });
225        self
226    }
227
228    /// Add a security scheme
229    pub fn add_security_scheme(mut self, name: &str, scheme: SecurityScheme) -> Self {
230        self.security_schemes.insert(name.to_string(), scheme);
231        self
232    }
233
234    /// Add a tag
235    pub fn add_tag(mut self, name: &str, description: Option<&str>) -> Self {
236        self.tags.push(TagConfig {
237            name: name.to_string(),
238            description: description.map(|s| s.to_string()),
239            external_docs: None,
240        });
241        self
242    }
243}