leetcode_api/entities/
index.rs1use 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}