rweb/
docs.rs

1use crate::openapi::Spec;
2use warp::{filters::BoxedFilter, Filter, Reply};
3
4/// Helper filter that exposes an openapi spec on the `/docs` endpoint.
5///
6/// # Example - single use with data injection
7///
8/// ```ignore
9/// let (spec, filter) = openapi::spec().build(|| index());
10/// serve(filter.or(openapi_docs(spec)))
11/// .run(([127, 0, 0, 1], 3030))
12/// .await;
13/// ```
14pub fn openapi_docs(spec: Spec) -> BoxedFilter<(impl Reply,)> {
15    let docs_openapi = warp::path("openapi.json").map(move || warp::reply::json(&spec.to_owned()));
16    let docs = warp::path("docs").map(|| {
17        warp::reply::html(
18            r#"
19            <!doctype html>
20            <html lang="en">
21            <head>
22            <title>rweb</title>
23            <link href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui.css" rel="stylesheet">
24            </head>
25            <body>
26                <div id="swagger-ui"></div>
27                <script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui-bundle.js" charset="UTF-8"> </script>
28                <script>
29                    window.onload = function() {
30                    const ui = SwaggerUIBundle({
31                        "dom_id": "\#swagger-ui",
32                        presets: [
33                        SwaggerUIBundle.presets.apis,
34                        SwaggerUIBundle.SwaggerUIStandalonePreset
35                        ],
36                        layout: "BaseLayout",
37                        deepLinking: true,
38                        showExtensions: true,
39                        showCommonExtensions: true,
40                        url: "/openapi.json",
41                    })
42                    window.ui = ui;
43                };
44            </script>
45            </body>
46            </html>
47        "#,
48        )
49    });
50    docs.or(docs_openapi).boxed()
51}