awesome_operates/
swagger.rs

1use std::fmt::Display;
2
3pub struct InitSwagger {
4    file_prefix: String,
5    pub js_filename: String,
6    pub index_html_filename: String,
7    pub json_uri: String,
8}
9
10/// generate swagger *.html and *initializer.js file with prefix
11/// the `json_url` just as a value in *initializer.js file
12/// eg.
13/// this will generate embed_files/swagger/index.html and
14/// embed_files/swagger/swagger-initializer.js(/swagger-json/api.json will be the key url value)
15/// ```rust,no_run
16/// use awesome_operates::swagger::InitSwagger;
17///
18/// #[tokio::test]
19/// async fn openapi_write() -> anyhow::Result<()> {
20///     awesome_operates::extract_all_files!(awesome_operates::embed::Asset);
21///     InitSwagger::new(
22///         "embed_files/swagger/",
23///         "swagger-initializer.js",
24///         "index.html",
25///         "/swagger-json/api.json"
26///     ).build().await.unwrap();
27///     Ok(())
28/// }
29/// ```
30impl InitSwagger {
31    pub fn new<T>(prefix: T, js_filename: T, index_html_filename: T, json_url: T) -> Self
32    where
33        T: Display,
34    {
35        InitSwagger {
36            file_prefix: prefix.to_string(),
37            js_filename: js_filename.to_string(),
38            index_html_filename: index_html_filename.to_string(),
39            json_uri: json_url.to_string(),
40        }
41    }
42
43    pub fn js_filepath(&self) -> String {
44        let prefix = std::path::Path::new(&self.file_prefix);
45        prefix.join(&self.js_filename).to_str().unwrap().to_owned()
46    }
47
48    pub fn index_html_filepath(&self) -> String {
49        let prefix = std::path::Path::new(&self.file_prefix);
50        prefix
51            .join(&self.index_html_filename)
52            .to_str()
53            .unwrap()
54            .to_owned()
55    }
56
57    pub async fn build(&self) -> anyhow::Result<()> {
58        self.rewrite_swagger_index_html().await?;
59        self.rewrite_swagger_initializer_js().await?;
60        Ok(())
61    }
62
63    pub async fn rewrite_swagger_index_html(&self) -> anyhow::Result<()> {
64        let index_html = format!(
65            r#"<!-- HTML for static distribution bundle build -->
66<!DOCTYPE html>
67<html lang="en">
68  <head>
69    <meta charset="UTF-8">
70    <title>Swagger UI</title>
71    <link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
72    <link rel="stylesheet" type="text/css" href="index.css" />
73    <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
74    <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
75  </head>
76
77  <body>
78    <div id="swagger-ui"></div>
79    <script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
80    <script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
81    <script src="./{}" charset="UTF-8"> </script>
82  </body>
83</html>
84"#,
85            self.js_filename
86        );
87        tracing::info!(
88            "write swagger index at path: {}",
89            self.index_html_filepath()
90        );
91        tokio::fs::write(&self.index_html_filepath(), index_html).await?;
92        Ok(())
93    }
94
95    pub async fn rewrite_swagger_initializer_js(&self) -> anyhow::Result<()> {
96        let js = format!(
97            r#"window.onload = function() {{
98  //<editor-fold desc="Changeable Configuration Block">
99
100  // the following lines will be replaced by docker/configurator, when it runs in a docker-container
101  window.ui = SwaggerUIBundle({{
102    url: "{}",
103    dom_id: '#swagger-ui',
104    deepLinking: true,
105    presets: [
106      SwaggerUIBundle.presets.apis,
107      SwaggerUIStandalonePreset
108    ],
109    plugins: [
110      SwaggerUIBundle.plugins.DownloadUrl
111    ],
112    layout: "StandaloneLayout",
113    defaultModelRendering: "model",
114    defaultModelsExpandDepth: 1,
115    defaultModelExpandDepth: 10,
116  }});
117
118  //</editor-fold>
119}};"#,
120            &self.json_uri
121        );
122        tracing::info!("write js initializer path: {}", self.js_filepath());
123        tokio::fs::write(&self.js_filepath(), js).await?;
124        Ok(())
125    }
126}