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

134 lines
2.9 KiB
Rust

#[cfg(feature = "rocket")]
use rocket::FromFormField;
#[cfg(feature = "openapi")]
use schemars::JsonSchema;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::{
fmt::Debug,
hash::Hash,
marker::PhantomData,
ops::{Deref, DerefMut},
};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum PartyError {
#[error("user `{0}` does not exist")]
UserNotFound(String),
#[error("event `{0}` does not exist")]
EventNotFound(String),
#[error("{0}")]
Other(String),
#[error("invalid parameter: {0}")]
InvalidParameter(String),
}
/// # Ordering
///
/// Ordering of data in an array, ascending or descending
#[derive(Clone, Debug)]
#[cfg_attr(feature = "openapi", derive(JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "rocket", derive(FromFormField))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Ordering {
#[cfg_attr(feature = "rocket", field(value = "desc"))]
Desc,
#[cfg_attr(feature = "rocket", field(value = "asc"))]
Asc,
}
impl ToString for Ordering {
fn to_string(&self) -> String {
match self {
Self::Desc => "DESC",
Self::Asc => "ASC",
}
.into()
}
}
#[derive(Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[serde(transparent)]
pub struct WithContext<Ctx, T> {
#[serde(skip)]
_ctx: PhantomData<Ctx>,
inner: T,
}
#[cfg(feature = "openapi")]
impl<Ctx, T> JsonSchema for WithContext<Ctx, T>
where
T: JsonSchema,
{
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
T::json_schema(gen)
}
fn schema_name() -> String {
T::schema_name()
}
}
impl<Ctx, T> Debug for WithContext<Ctx, T>
where
T: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl<Ctx, T> Hash for WithContext<Ctx, T>
where
T: Hash,
{
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.inner.hash(state)
}
}
impl<Ctx, T> PartialEq for WithContext<Ctx, T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}
impl<Ctx, T> Eq for WithContext<Ctx, T> where T: Eq {}
impl<Ctx, T> Deref for WithContext<Ctx, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<Ctx, T> DerefMut for WithContext<Ctx, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<Ctx, T> From<T> for WithContext<Ctx, T> {
fn from(inner: T) -> Self {
Self {
_ctx: PhantomData,
inner,
}
}
}
#[cfg(feature = "sycamore")]
use sycamore::reactive::{ReadSignal, Scope};
#[cfg(feature = "sycamore")]
pub trait ContextOptions<T> {
fn options<'a>(&'a self, cx: Scope<'a>) -> &'a ReadSignal<Vec<T>>;
}