ord 0.27.1

◉ Ordinal wallet and block explorer
Documentation
use {super::*, std::fmt::Write};

#[derive(Debug)]
pub(super) enum ServerError {
  BadRequest(String),
  Internal(Error),
  NotAcceptable {
    accept_encoding: AcceptEncoding,
    content_encoding: HeaderValue,
  },
  NotFound(String),
}

pub(super) type ServerResult<T = Response> = Result<T, ServerError>;

impl IntoResponse for ServerError {
  fn into_response(self) -> Response {
    match self {
      Self::BadRequest(message) => (StatusCode::BAD_REQUEST, message).into_response(),
      Self::Internal(error) => {
        eprintln!("error serving request: {error}");
        (
          StatusCode::INTERNAL_SERVER_ERROR,
          StatusCode::INTERNAL_SERVER_ERROR
            .canonical_reason()
            .unwrap_or_default(),
        )
          .into_response()
      }
      Self::NotAcceptable {
        accept_encoding,
        content_encoding,
      } => {
        let mut message = format!(
          "inscription content encoding `{}` is not acceptable.",
          String::from_utf8_lossy(content_encoding.as_bytes())
        );

        if let Some(accept_encoding) = accept_encoding.0 {
          write!(message, " `Accept-Encoding` header: `{accept_encoding}`").unwrap();
        } else {
          write!(message, " `Accept-Encoding` header not present").unwrap();
        };

        (StatusCode::NOT_ACCEPTABLE, message).into_response()
      }
      Self::NotFound(message) => (
        StatusCode::NOT_FOUND,
        [(header::CACHE_CONTROL, HeaderValue::from_static("no-store"))],
        message,
      )
        .into_response(),
    }
  }
}

pub(super) trait OptionExt<T> {
  fn ok_or_not_found<F: FnOnce() -> S, S: Into<String>>(self, f: F) -> ServerResult<T>;
}

impl<T> OptionExt<T> for Option<T> {
  fn ok_or_not_found<F: FnOnce() -> S, S: Into<String>>(self, f: F) -> ServerResult<T> {
    match self {
      Some(value) => Ok(value),
      None => Err(ServerError::NotFound(f().into() + " not found")),
    }
  }
}

impl From<Error> for ServerError {
  fn from(error: Error) -> Self {
    Self::Internal(error)
  }
}