#[must_use]
pub struct Scalar {
title: String,
spec_url: String,
}
impl Scalar {
pub fn new(spec_url: impl Into<String>) -> Self {
Self {
title: "Scalar".into(),
spec_url: spec_url.into(),
}
}
pub fn with_title(mut self, title: &str) -> Self {
self.title = title.into();
self
}
#[must_use]
pub fn html(&self) -> String {
format!(
r#"<!DOCTYPE html>
<!doctype html>
<html>
<head>
<title>{title}</title>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1" />
<style>
body {{
margin: 0;
}}
</style>
</head>
<body>
<script
id="api-reference"></script>
<script>
var configuration = {{
theme: 'purple',
customCss: `{scalar_css}`,
spec: {{
url: '{spec_url}'
}}
}}
var apiReference = document.getElementById('api-reference')
apiReference.dataset.configuration = JSON.stringify(configuration)
</script>
<script>
{scalar_js}
</script>
</body>
</html>
"#,
scalar_js = include_str!("../../res/scalar/scalar.standalone.min.js"),
scalar_css = include_str!("../../res/scalar/rust-theme.css"),
title = self.title,
spec_url = self.spec_url
)
}
}
#[cfg(feature = "axum")]
mod axum_impl {
use crate::axum::{
routing::{get, ApiMethodRouter},
AxumOperationHandler,
};
use axum::response::Html;
impl super::Scalar {
pub fn axum_route<S>(&self) -> ApiMethodRouter<S>
where
S: Clone + Send + Sync + 'static,
{
get(self.axum_handler())
}
#[must_use]
pub fn axum_handler<S>(
&self,
) -> impl AxumOperationHandler<(), Html<&'static str>, ((),), S> {
let html = self.html();
let html: &'static str = get_static_str(html);
move || async move { Html(html) }
}
}
fn get_static_str(string: String) -> &'static str {
let static_str = Box::leak(string.into_boxed_str());
static_str
}
}