use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
/// What's stored in `rankings.rank`. The domain type is [`Rank`], which
/// carries `Obsessed`'s date; this is just its tag.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(rs_type = "String", db_type = "String(StringLen::N(16))")]
#[serde(rename_all = "lowercase")]
pub enum RankKind {
#[sea_orm(string_value = "obsessed")]
Obsessed,
#[sea_orm(string_value = "always")]
Always,
#[sea_orm(string_value = "positive")]
Positive,
/// Not been yet, want to go.
#[sea_orm(string_value = "to_try")]
ToTry,
#[sea_orm(string_value = "neutral")]
Neutral,
#[sea_orm(string_value = "never")]
Never,
}
impl RankKind {
/// Strongest first — the order the rank buttons appear in.
pub const ALL: [RankKind; 6] = [
RankKind::Obsessed,
RankKind::Always,
RankKind::Positive,
RankKind::ToTry,
RankKind::Neutral,
RankKind::Never,
];
pub fn as_str(self) -> &'static str {
match self {
RankKind::Obsessed => "obsessed",
RankKind::Always => "always",
RankKind::Positive => "positive",
RankKind::ToTry => "to_try",
RankKind::Neutral => "neutral",
RankKind::Never => "never",
}
}
pub fn parse(s: &str) -> Option<RankKind> {
RankKind::ALL.into_iter().find(|r| r.as_str() == s)
}
}
/// How one person feels about one restaurant. Unranked counts as `Neutral`.
///
/// Serializes as its kind's name ("obsessed", "always", …), which is what
/// templates and the map compare against; read `since` with [`Rank::since`].
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Rank {
Obsessed { since: Date },
Always,
Positive,
/// Not been yet, want to go. Once you have been (see `crate::suggest`),
/// it counts as Neutral until you rank it properly.
ToTry,
Neutral,
Never,
}
impl Rank {
pub fn kind(self) -> RankKind {
match self {
Rank::Obsessed { .. } => RankKind::Obsessed,
Rank::Always => RankKind::Always,
Rank::Positive => RankKind::Positive,
Rank::ToTry => RankKind::ToTry,
Rank::Neutral => RankKind::Neutral,
Rank::Never => RankKind::Never,
}
}
pub fn as_str(self) -> &'static str {
self.kind().as_str()
}
pub fn since(self) -> Option<Date> {
match self {
Rank::Obsessed { since } => Some(since),
_ => None,
}
}
/// Rebuild from the two columns. `fallback` dates an obsession whose
/// `obsessed_since` is somehow missing.
pub fn from_parts(kind: RankKind, since: Option<Date>, fallback: Date) -> Rank {
match kind {
RankKind::Obsessed => Rank::Obsessed { since: since.unwrap_or(fallback) },
RankKind::Always => Rank::Always,
RankKind::Positive => Rank::Positive,
RankKind::ToTry => Rank::ToTry,
RankKind::Neutral => Rank::Neutral,
RankKind::Never => Rank::Never,
}
}
}
impl Serialize for Rank {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(self.as_str())
}
}
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "rankings")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub user_id: Uuid,
#[sea_orm(primary_key, auto_increment = false)]
pub restaurant_id: Uuid,
pub rank: RankKind,
/// Set exactly when `rank` is `Obsessed`.
pub obsessed_since: Option<Date>,
pub updated_at: DateTimeWithTimeZone,
}
impl Model {
pub fn rank(&self) -> Rank {
Rank::from_parts(self.rank, self.obsessed_since, self.updated_at.date_naive())
}
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::restaurants::Entity",
from = "Column::RestaurantId",
to = "super::restaurants::Column::Id",
on_delete = "Cascade"
)]
Restaurants,
#[sea_orm(
belongs_to = "super::users::Entity",
from = "Column::UserId",
to = "super::users::Column::Id",
on_delete = "Cascade"
)]
Users,
}
impl Related<super::restaurants::Entity> for Entity {
fn to() -> RelationDef {
Relation::Restaurants.def()
}
}
impl Related<super::users::Entity> for Entity {
fn to() -> RelationDef {
Relation::Users.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
neiam
/fieri-forever
the flavortown lunch engine
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
4.6 KiB · text
History
7a00c02