nanocl_utils 0.1.1

Nanocl shared utils
Documentation
use std::sync::Arc;

use ntex::web;
use ntex::http;
use ntex::util::Bytes;

use crate::http_error::HttpError;

pub struct SwaggerConfig<'a> {
  definition: utoipa::openapi::OpenApi,
  config: Arc<utoipa_swagger_ui::Config<'a>>,
}

impl<'a> SwaggerConfig<'a> {
  pub fn new(definition: utoipa::openapi::OpenApi, def_url: &'a str) -> Self {
    Self {
      definition,
      config: Arc::new(
        utoipa_swagger_ui::Config::new([def_url]).use_base_layout(),
      ),
    }
  }

  pub fn config(&mut self, config: utoipa_swagger_ui::Config<'a>) -> &mut Self {
    self.config = Arc::new(config);
    self
  }
}

#[web::get("/swagger.json")]
async fn get_specs(
  openapi_conf: web::types::State<SwaggerConfig<'static>>,
) -> Result<web::HttpResponse, HttpError> {
  let spec = openapi_conf.definition.to_json().map_err(|err| HttpError {
    status: http::StatusCode::INTERNAL_SERVER_ERROR,
    msg: format!("Error generating OpenAPI spec: {}", err),
  })?;
  return Ok(
    web::HttpResponse::Ok()
      .content_type("application/json")
      .body(spec),
  );
}

#[web::get("/{tail}*")]
async fn get_swagger(
  tail: web::types::Path<String>,
  openapi_conf: web::types::State<SwaggerConfig<'static>>,
) -> Result<web::HttpResponse, HttpError> {
  match utoipa_swagger_ui::serve(&tail, openapi_conf.config.clone())
    .map_err(|err| HttpError::internal_server_error(err.to_string()))?
  {
    None => Err(HttpError::not_found("Path not handled")),
    Some(file) => Ok({
      let bytes = Bytes::from(file.bytes.to_vec());
      web::HttpResponse::Ok()
        .content_type(file.content_type)
        .body(bytes)
    }),
  }
}

pub fn register(config: &mut web::ServiceConfig) {
  config.service(get_specs);
  config.service(get_swagger);
}