apistos_plugins/
ui.rs

1use actix_web::dev::{AppService, HttpServiceFactory};
2use actix_web::guard::Get;
3use actix_web::web::Data;
4use actix_web::{HttpResponse, Resource, Responder};
5
6/// Trait to implement on a UI config which will serve a an argument of `BuildConfig::with` method
7pub trait UIPluginConfig {
8  /// Build a `UIPlugin` given a `UIPluginConfig` and an `openapi_path`
9  fn build(self: Box<Self>, openapi_path: &str) -> Box<dyn UIPlugin>;
10}
11
12/// Trait to implement to expose a UI for the generated openapi specification
13pub trait UIPlugin {
14  /// Getter for the HTML file path
15  fn path(&self) -> String;
16
17  /// Transform the given file (defined at `path`) to a valid HTML String. Useful for variable replacement for example.
18  fn to_html(&self) -> String;
19}
20
21impl UIPlugin for Box<dyn UIPlugin> {
22  fn path(&self) -> String {
23    self.as_ref().path()
24  }
25
26  fn to_html(&self) -> String {
27    self.as_ref().to_html()
28  }
29}
30
31#[doc(hidden)]
32pub struct UIPluginWrapper(Box<dyn UIPlugin>);
33
34impl From<Box<dyn UIPlugin>> for UIPluginWrapper {
35  fn from(value: Box<dyn UIPlugin>) -> Self {
36    Self(value)
37  }
38}
39
40impl HttpServiceFactory for UIPluginWrapper {
41  fn register(self, config: &mut AppService) {
42    async fn handler(html: Data<String>) -> impl Responder {
43      HttpResponse::Ok().content_type("text/html").body(html.to_string())
44    }
45
46    let html = self.0.to_html();
47    Resource::new::<&str>(&self.0.path())
48      .guard(Get())
49      .app_data(Data::new(html))
50      .to(handler)
51      .register(config);
52  }
53}