lan-party-backend/backend/src/api/util.rs

111 lines
2.8 KiB
Rust

use std::borrow::Borrow;
use rocket::{
http::Status,
response::{self, status, Responder},
Request,
};
use rocket_db_pools::mongodb;
use rocket_okapi::response::OpenApiResponderInner;
use schemars::JsonSchema;
use thiserror::Error;
use lan_party_core::{event::Event, user::User, util::PartyError as CoreError};
/// # Ordering
///
/// Ordering of data in an array, ascending or descending
#[derive(Clone, Debug, FromFormField, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum Ordering {
#[field(value = "desc")]
Desc,
#[field(value = "asc")]
Asc,
}
impl ToString for Ordering {
fn to_string(&self) -> String {
match self {
Self::Desc => "DESC",
Self::Asc => "ASC",
}
.into()
}
}
#[derive(Error, Debug)]
pub enum PartyError {
#[error("{source}")]
CoreError {
#[from]
source: CoreError,
},
#[error("uuid error {source:?}")]
UuidError {
#[from]
source: uuid::Error,
},
#[error("mongodb error {source:?}")]
MongodbError {
#[from]
source: mongodb::error::Error,
},
#[error("failed to serialize bson: {source:?}")]
BsonSerializationError {
#[from]
source: mongodb::bson::ser::Error,
},
#[error("user `{0}` does not exist")]
UserNotFound(String),
#[error("event `{0}` does not exist")]
EventNotFound(String),
#[error("unknown error: {0}")]
Unknown(String),
}
impl OpenApiResponderInner for PartyError {
fn responses(
_gen: &mut rocket_okapi::gen::OpenApiGenerator,
) -> rocket_okapi::Result<okapi::openapi3::Responses> {
Ok(okapi::openapi3::Responses::default())
}
}
impl<'r, 'o: 'r> Responder<'r, 'o> for PartyError {
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> {
println!("{}", self.to_string());
let message = self.to_string();
match self {
Self::CoreError { source } => match source {
CoreError::UserNotFound(_) | CoreError::EventNotFound(_) => {
(Status::NotFound, "not found".to_string())
}
_ => (Status::BadRequest, message),
},
_ => (Status::InternalServerError, "unknown error".to_string()),
}
.respond_to(req)
}
}
pub trait MongoClientExt {
fn party_db(&self) -> mongodb::Database;
fn users(&self) -> mongodb::Collection<User>;
fn events(&self) -> mongodb::Collection<Event>;
}
impl MongoClientExt for mongodb::Client {
fn party_db(&self) -> mongodb::Database {
self.database("lan_party")
}
fn users(&self) -> mongodb::Collection<User> {
self.party_db().collection("users")
}
fn events(&self) -> mongodb::Collection<Event> {
self.party_db().collection("events")
}
}