use std::borrow::Cow;
pub mod auth;
pub mod kind;
pub mod language;
pub mod media_file;
pub mod podcast;
pub mod podcast_episode;
pub mod podcast_subscription;
pub mod podcast_task;
pub mod prelude;
pub mod task;
pub mod tvshow;
pub mod tvshow_episode;
pub mod tvshow_season;
pub mod tvshow_subscription;
fn default_includes<T>() -> Vec<T> {
Vec::new()
}
pub trait IsVoid {
fn is_void(&self) -> bool;
}
impl IsVoid for () {
fn is_void(&self) -> bool {
true
}
}
impl<T> IsVoid for Vec<T> {
fn is_void(&self) -> bool {
self.is_empty()
}
}
impl<T> IsVoid for Option<T> {
fn is_void(&self) -> bool {
self.is_none()
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Entity<Id, Kind> {
pub id: Id,
#[serde(rename = "type")]
pub kind: Kind,
}
impl<Id, Kind: Default> Entity<Id, Kind> {
pub fn new(id: Id) -> Self {
Self {
id,
kind: Default::default(),
}
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ApiResource<T, Inc = ()> {
pub data: T,
#[serde(default = "default_includes", skip_serializing_if = "Vec::is_empty")]
pub includes: Vec<Inc>,
}
impl<T> ApiResource<T> {
pub fn new(data: T) -> Self {
Self {
data,
includes: Vec::new(),
}
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Relation<T, Meta = ()>
where
Meta: IsVoid,
{
pub data: Option<T>,
#[serde(default, skip_serializing_if = "IsVoid::is_void")]
pub meta: Meta,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct ApiError {
pub message: Cow<'static, str>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub detail: Option<ApiErrorDetail>,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct ApiErrorDetail {
pub attribute: Cow<'static, str>,
pub code: Cow<'static, str>,
}
impl ApiErrorDetail {
pub fn new(
attribute: impl Into<Cow<'static, str>>,
code: impl Into<Cow<'static, str>>,
) -> Self {
Self {
attribute: attribute.into(),
code: code.into(),
}
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Couple(pub u64, pub u64);
impl serde::Serialize for Couple {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let value = format!("{}#{}", self.0, self.1);
serializer.serialize_str(value.as_str())
}
}
impl<'de> serde::de::Deserialize<'de> for Couple {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
let Some((left, right)) = value.split_once('#') else {
return Err(serde::de::Error::custom("invalid format"));
};
let left = left.parse::<u64>().map_err(serde::de::Error::custom)?;
let right = right.parse::<u64>().map_err(serde::de::Error::custom)?;
Ok(Couple(left, right))
}
}