134 lines
2.9 KiB
Rust
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>>;
|
|
}
|