leetcode_api/entities/
index.rs

1use std::fmt::Display;
2
3use colored::Colorize;
4use sea_orm::entity::prelude::*;
5use serde::{Deserialize, Serialize};
6use unicode_width::UnicodeWidthChar;
7
8use crate::leetcode::question::qs_index::QsIndex;
9
10#[derive(Clone)]
11#[derive(Debug)]
12#[derive(Default)]
13#[derive(PartialEq)]
14#[derive(Serialize, Deserialize)]
15#[derive(DeriveEntityModel)]
16#[sea_orm(table_name = "problem_index")]
17pub struct Model {
18    #[sea_orm(primary_key, auto_increment = false)]
19    #[serde(default)]
20    pub question_id: u32,
21    #[serde(default)]
22    pub question_title: String,
23    #[serde(default)]
24    pub question_title_slug: String,
25    #[serde(default)]
26    pub total_acs: u32,
27    #[serde(default)]
28    pub total_submitted: u32,
29    #[serde(default)]
30    pub frontend_question_id: String,
31    #[serde(default)]
32    pub status: Option<String>,
33    #[serde(default)]
34    pub difficulty: u32,
35    #[serde(default)]
36    pub paid_only: bool,
37    #[serde(default)]
38    pub is_favor: bool,
39    #[serde(default)]
40    pub frequency: u32,
41    #[serde(default)]
42    pub progress: u32,
43    #[serde(default)]
44    pub category: String,
45    #[serde(default)]
46    pub pass_rate: Option<f64>,
47}
48
49impl From<QsIndex> for Model {
50    fn from(value: QsIndex) -> Self {
51        Self {
52            question_id: value.stat.question_id,
53            question_title: value.stat.question_title,
54            question_title_slug: value.stat.question_title_slug,
55            total_acs: value.stat.total_acs,
56            total_submitted: value.stat.total_submitted,
57            frontend_question_id: value.stat.frontend_question_id,
58            status: value.status,
59            difficulty: value.difficulty.level,
60            paid_only: value.paid_only,
61            is_favor: value.is_favor,
62            frequency: value.frequency,
63            progress: value.progress,
64            category: String::new(),
65            pass_rate: Some(
66                value.stat.total_acs as f64 / value.stat.total_submitted as f64 * 100.0,
67            ),
68        }
69    }
70}
71
72#[derive(Clone, Copy)]
73#[derive(Debug)]
74#[derive(Default)]
75#[derive(PartialEq, Eq)]
76#[derive(EnumIter, DeriveRelation)]
77pub enum Relation {
78    #[default]
79    #[sea_orm(has_one = "super::detail::Entity")]
80    Detail,
81}
82
83impl Related<super::detail::Entity> for Entity {
84    fn to() -> RelationDef {
85        Relation::Detail.def()
86    }
87}
88
89impl ActiveModelBehavior for ActiveModel {}
90
91impl Display for Model {
92    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        let diff = match self.difficulty {
94            1 => "⛳Easy".green(),
95            2 => "🕎Medium".yellow(),
96            3 => "💀Hard".red(),
97            _ => " Unknown".blue(),
98        };
99
100        let mut id_width = 14;
101        for ch in self.frontend_question_id.chars() {
102            match UnicodeWidthChar::width(ch).unwrap_or_default() {
103                0 | 1 => {},
104                w => id_width -= w - 1,
105            }
106        }
107
108        let mut tit_wid = 66;
109        for ch in self.question_title.chars() {
110            match UnicodeWidthChar::width(ch).unwrap_or_default() {
111                0 | 1 => {},
112                w => tit_wid -= w - 1,
113            }
114        }
115
116        format!(
117            "🆔[{id:07}]|{fid:id_width$}|{cg:11}|🇹: {tit:tit_wid$}|Pass: {percent:.2}%|PaidOnly: \
118             {po:6}|{diff:8}|{st}",
119            fid = self.frontend_question_id,
120            id = self.question_id,
121            cg = self.category,
122            tit = self.question_title,
123            percent = self.pass_rate.unwrap_or_default(),
124            po = self.paid_only,
125            diff = diff,
126            st = if self.status.is_some() { "👍" } else { "" }
127        )
128        .fmt(f)
129    }
130}