Skip to content

Commit

Permalink
Allow openapi UIs setting lib_url (#461)
Browse files Browse the repository at this point in the history
* wip

* Allow openapi UIs setting `lib_url`
  • Loading branch information
chrislearn authored Oct 18, 2023
1 parent edba893 commit db1b81d
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 51 deletions.
28 changes: 17 additions & 11 deletions crates/oapi/src/rapidoc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const INDEX_TMPL: &str = r#"
<html>
<head>
<meta charset="utf-8">
<script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
<script type="module" src="{{lib_url}}"></script>
</head>
<body>
<rapi-doc spec-url="{{spec_url}}"></rapi-doc>
Expand All @@ -21,10 +21,13 @@ const INDEX_TMPL: &str = r#"
"#;

/// Implements [`Handler`] for serving RapiDoc.
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct RapiDoc {
spec_url: String,
html: String,
/// The lib url path.
pub lib_url: String,
/// The spec url path.
pub spec_url: String,
}
impl RapiDoc {
/// Create a new [`RapiDoc`] for given path.
Expand All @@ -39,16 +42,16 @@ impl RapiDoc {
/// let doc = RapiDoc::new("/openapi.json");
/// ```
pub fn new(spec_url: impl Into<String>) -> Self {
let spec_url = spec_url.into();
Self {
html: INDEX_TMPL.replace("{{spec_url}}", &spec_url),
spec_url,
lib_url: "https://unpkg.com/rapidoc/dist/rapidoc-min.js".into(),
spec_url: spec_url.into(),
}
}

/// Returns the spec url.
pub fn sepec_url(&self) -> &str {
&self.spec_url
/// Set the lib url path.
pub fn lib_url(mut self, lib_url: impl Into<String>) -> Self {
self.lib_url = lib_url.into();
self
}

/// Consusmes the [`RapiDoc`] and returns [`Router`] with the [`RapiDoc`] as handler.
Expand All @@ -60,6 +63,9 @@ impl RapiDoc {
#[async_trait]
impl Handler for RapiDoc {
async fn handle(&self, _req: &mut Request, _depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) {
res.render(Text::Html(&self.html));
let html = INDEX_TMPL
.replace("{{lib_url}}", &self.lib_url)
.replace("{{spec_url}}", &self.spec_url);
res.render(Text::Html(html));
}
}
}
37 changes: 20 additions & 17 deletions crates/oapi/src/redoc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ const INDEX_TMPL: &str = r#"
<title>Redoc</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700"
rel="stylesheet"
/>
<link href="{{css_url}}" rel="stylesheet"/>
<style>
body {
margin: 0;
Expand All @@ -28,7 +25,7 @@ const INDEX_TMPL: &str = r#"
<body>
<div id="redoc-container"></div>
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>
<script src="{{lib_url}}"></script>
<script>
Redoc.init(
"{{spec_url}}",
Expand All @@ -38,15 +35,18 @@ const INDEX_TMPL: &str = r#"
</script>
</body>
</html>
"#;

/// Implements [`Handler`] for serving ReDoc.
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct ReDoc {
spec_url: String,
html: String,
/// The lib url path.
pub lib_url: String,
/// The spec url path.
pub spec_url: String,
}

impl ReDoc {
/// Create a new [`ReDoc`] for given path.
///
Expand All @@ -60,17 +60,17 @@ impl ReDoc {
/// let doc = ReDoc::new("/openapi.json");
/// ```
pub fn new(spec_url: impl Into<String>) -> Self {
let spec_url = spec_url.into();
Self {
html: INDEX_TMPL.replace("{{spec_url}}", &spec_url),
spec_url,
lib_url: "https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js".into(),
spec_url: spec_url.into(),
}
}

/// Returns the spec url.
pub fn sepec_url(&self) -> &str {
&self.spec_url
}
/// Set the lib url path.
pub fn lib_url(mut self, lib_url: impl Into<String>) -> Self {
self.lib_url = lib_url.into();
self
}

/// Consusmes the [`ReDoc`] and returns [`Router`] with the [`ReDoc`] as handler.
pub fn into_router(self, path: impl Into<String>) -> Router {
Expand All @@ -81,6 +81,9 @@ impl ReDoc {
#[async_trait]
impl Handler for ReDoc {
async fn handle(&self, _req: &mut Request, _depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) {
res.render(Text::Html(&self.html));
let html = INDEX_TMPL
.replace("{{lib_url}}", &self.lib_url)
.replace("{{spec_url}}", &self.spec_url);
res.render(Text::Html(html));
}
}
}
44 changes: 23 additions & 21 deletions crates/oapi/src/scalar/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! This crate implements necessary boiler plate code to serve ReDoc via web server. It
//! This crate implements necessary boiler plate code to serve Scalar via web server. It
//! works as a bridge for serving the OpenAPI documentation created with [`salvo`][salvo] library in the
//! ReDoc.
//! Scalar.
//!
//! [salvo]: <https://docs.rs/salvo/>
//!
Expand All @@ -14,10 +14,6 @@ const INDEX_TMPL: &str = r#"
<title>Scalar</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700"
rel="stylesheet"
/>
<style>
body {
margin: 0;
Expand All @@ -28,22 +24,25 @@ const INDEX_TMPL: &str = r#"
<body>
<script id="api-reference" data-url="{{spec_url}}"></script>
<script src="https://www.unpkg.com/@scalar/api-reference"></script>
<script src="{{lib_url}}"></script>
</body>
</html>
"#;

/// Implements [`Handler`] for serving ReDoc.
/// Implements [`Handler`] for serving Scalar.
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct Scalar {
spec_url: String,
html: String,
/// The lib url path.
pub lib_url: String,
/// The spec url path.
pub spec_url: String,
}
impl Scalar {
/// Create a new [`ReDoc`] for given path.
/// Create a new [`Scalar`] for given path.
///
/// Path argument will expose the ReDoc to the user and should be something that
/// Path argument will expose the Scalar to the user and should be something that
/// the underlying application framework / library supports.
///
/// # Examples
Expand All @@ -53,27 +52,30 @@ impl Scalar {
/// let doc = Scalar::new("/openapi.json");
/// ```
pub fn new(spec_url: impl Into<String>) -> Self {
let spec_url = spec_url.into();
Self {
html: INDEX_TMPL.replace("{{spec_url}}", &spec_url),
spec_url,
lib_url: "https://www.unpkg.com/@scalar/api-reference".into(),
spec_url: spec_url.into(),
}
}

/// Returns the spec url.
pub fn sepec_url(&self) -> &str {
&self.spec_url
/// Set the lib url path.
pub fn lib_url(mut self, lib_url: impl Into<String>) -> Self {
self.lib_url = lib_url.into();
self
}


/// Consusmes the [`Scalar`] and returns [`Router`] with the [`Scalar`] as handler.
pub fn into_router(self, path: impl Into<String>) -> Router {
Router::with_path(path.into()).goal(self)
}
}

#[async_trait]
impl Handler for Scalar {
async fn handle(&self, _req: &mut Request, _depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) {
res.render(Text::Html(&self.html));
let html = INDEX_TMPL
.replace("{{lib_url}}", &self.lib_url)
.replace("{{spec_url}}", &self.spec_url);
res.render(Text::Html(html));
}
}
}
2 changes: 0 additions & 2 deletions crates/oapi/src/swagger_ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ const INDEX_TMPL: &str = r#"
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html {
box-sizing: border-box;
Expand Down
Binary file removed crates/oapi/src/swagger_ui/v5.9.0/favicon-16x16.png
Binary file not shown.
Binary file removed crates/oapi/src/swagger_ui/v5.9.0/favicon-32x32.png
Binary file not shown.

0 comments on commit db1b81d

Please sign in to comment.