sz_rust_http_facade/
openapi.rs1use thiserror::Error;
6
7#[derive(Debug, Error)]
9pub enum OpenApiError {
10 #[error("OpenAPI build error: {0}")]
12 Build(String),
13 #[error("JSON serialize error: {0}")]
15 Serialize(String),
16}
17
18pub struct OpenApiBuilder {
22 title: String,
23 version: String,
24 description: Option<String>,
25}
26
27impl OpenApiBuilder {
28 pub fn new(title: impl Into<String>, version: impl Into<String>) -> Self {
30 Self {
31 title: title.into(),
32 version: version.into(),
33 description: None,
34 }
35 }
36
37 pub fn description(mut self, desc: impl Into<String>) -> Self {
39 self.description = Some(desc.into());
40 self
41 }
42
43 pub fn build(self) -> utoipa::openapi::Info {
45 let mut info = utoipa::openapi::Info::default();
46 info.title = self.title;
47 info.version = self.version;
48 info.description = self.description;
49 info
50 }
51
52 pub fn to_json(self) -> Result<String, OpenApiError> {
54 let info = self.build();
55 serde_json::to_string_pretty(&info)
56 .map_err(|e| OpenApiError::Serialize(e.to_string()))
57 }
58
59 pub fn validate(self) -> Result<(), OpenApiError> {
61 let info = self.build();
62 if info.title.is_empty() {
63 return Err(OpenApiError::Build("title is empty".into()));
64 }
65 if info.version.is_empty() {
66 return Err(OpenApiError::Build("version is empty".into()));
67 }
68 Ok(())
69 }
70}
71
72#[cfg(feature = "swagger-ui")]
76pub fn swagger_ui_routes() -> axum::Router {
77 utoipa_swagger_ui::SwaggerUi::new("/docs/{_:.*}")
78 .url("/api-docs/openapi.json", utoipa::OpenApi::default())
79 .into()
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn test_openapi_build() {
88 let info = OpenApiBuilder::new("Test API", "1.0.0").build();
89 assert_eq!(info.title, "Test API");
90 assert_eq!(info.version, "1.0.0");
91 }
92
93 #[test]
94 fn test_openapi_to_json() {
95 let json = OpenApiBuilder::new("Test API", "1.0.0").to_json().unwrap();
96 assert!(json.contains("Test API"));
97 assert!(json.contains("1.0.0"));
98 }
99
100 #[test]
101 fn test_openapi_validate() {
102 let result = OpenApiBuilder::new("Test", "1.0").validate();
103 assert!(result.is_ok());
104 }
105
106 #[test]
107 fn test_openapi_validate_empty_title() {
108 let result = OpenApiBuilder::new("", "1.0").validate();
109 assert!(result.is_err());
110 }
111
112 #[test]
113 fn test_openapi_error_display() {
114 let err = OpenApiError::Build("test error".into());
115 assert_eq!(err.to_string(), "OpenAPI build error: test error");
116 }
117}