game_manager_lib/
models.rs

1//! Modelos de dados do banco de dados.
2//!
3//! Define as structs que representam as tabelas do banco:
4//! - Game: tabela `games`
5//! - GameDetails: tabela `game_details`
6//! - WishlistGame: tabela `wishlist`
7
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11// Reexportar GameTag do utils para consistência
12pub use crate::utils::tag_utils::GameTag;
13
14// === Modelos de Dados ===
15
16/// Jogo na biblioteca do usuário.
17///
18/// Representa um jogo adicionado à biblioteca pessoal, com metadados
19/// importados da plataforma e dados de progresso do usuário.
20#[derive(Debug, Serialize, Deserialize, Clone)]
21pub struct Game {
22    pub id: String,
23    pub name: String,
24    #[serde(rename = "coverUrl")]
25    pub cover_url: Option<String>,
26    pub genres: Option<String>,
27    pub developer: Option<String>,
28
29    // Identificação
30    pub platform: String,
31    #[serde(rename = "platformId")]
32    pub platform_id: Option<String>,
33
34    // Execução
35    #[serde(rename = "installPath")]
36    pub install_path: Option<String>,
37    #[serde(rename = "executablePath")]
38    pub executable_path: Option<String>,
39    #[serde(rename = "launchArgs")]
40    pub launch_args: Option<String>,
41
42    // Dados do Usuário
43    #[serde(rename = "userRating")]
44    pub user_rating: Option<i32>,
45    pub favorite: bool,
46    pub status: Option<String>,
47
48    // Metadados de Tempo
49    pub playtime: Option<i32>,
50    #[serde(rename = "lastPlayed")]
51    pub last_played: Option<String>,
52    #[serde(rename = "addedAt")]
53    pub added_at: String,
54
55    // Conteúdo Adulto
56    #[serde(default, rename = "isAdult")]
57    pub is_adult: bool,
58}
59
60/// Detalhes adicionais do jogo (Schema v3).
61///
62/// Contém metadados enriquecidos obtidos de APIs externas como RAWG,
63/// substituindo e expandindo os dados anteriores.
64#[derive(Debug, Serialize, Deserialize)]
65pub struct GameDetails {
66    #[serde(rename = "gameId")]
67    pub game_id: String,
68
69    #[serde(rename = "steamAppId")]
70    pub steam_app_id: Option<String>,
71
72    // Metadados Básicos
73    pub developer: Option<String>,
74    pub publisher: Option<String>,
75
76    #[serde(rename = "releaseDate")]
77    pub release_date: Option<String>,
78
79    // Categorização
80    pub genres: Option<String>,
81    pub tags: Option<Vec<GameTag>>, // Array de tags categorizadas
82    pub series: Option<String>,
83
84    // Descrição
85    #[serde(rename = "descriptionRaw")]
86    pub description_raw: Option<String>,
87
88    #[serde(rename = "descriptionPtbr")]
89    pub description_ptbr: Option<String>,
90
91    // Mídia
92    #[serde(rename = "backgroundImage")]
93    pub background_image: Option<String>,
94
95    // Scores
96    #[serde(rename = "criticScore")]
97    pub critic_score: Option<i32>, // Metacritic
98
99    // Steam Reviews
100    #[serde(rename = "steamReviewLabel")]
101    pub steam_review_label: Option<String>, // "Very Positive", "Mixed", etc.
102
103    #[serde(rename = "steamReviewCount")]
104    pub steam_review_count: Option<i32>,
105
106    #[serde(rename = "steamReviewScore")]
107    pub steam_review_score: Option<f32>, // Porcentagem de positivos (0-100)
108
109    #[serde(rename = "steamReviewUpdatedAt")]
110    pub steam_review_updated_at: Option<String>,
111
112    // Conteúdo Adulto
113    #[serde(rename = "esrbRating")]
114    pub esrb_rating: Option<String>, // "E", "T", "M", etc.
115
116    #[serde(rename = "isAdult")]
117    pub is_adult: bool,
118
119    #[serde(rename = "adultTags")]
120    pub adult_tags: Option<String>, // Nudity, Gore, Sexual Content, etc.
121
122    // Links Externos
123    #[serde(rename = "externalLinks")]
124    pub external_links: Option<HashMap<String, String>>,
125    // Exemplo: {"website": "...", "steam": "...", "rawg": "...", "reddit": "..."}
126
127    // Tempo de Jogo (Alternativa a HLTB)
128    #[serde(rename = "medianPlaytime")]
129    pub median_playtime: Option<i32>, // Mediana do SteamSpy em horas
130
131    // Estimativa de Tempo de Jogo
132    #[serde(rename = "estimatedPlaytime")]
133    pub estimated_playtime: Option<f32>, // Tempo estimado em horas (história principal)
134}
135
136/// Jogo na lista de desejos (wishlist) com tracking de preços.
137///
138/// Representa um jogo adicionado à wishlist do usuário,
139/// incluindo informações de preço, disponibilidade e vouchers.
140#[derive(Debug, Serialize, Deserialize)]
141pub struct WishlistGame {
142    pub id: String,
143    pub name: String,
144
145    #[serde(rename = "coverUrl")]
146    pub cover_url: Option<String>,
147
148    #[serde(rename = "storeUrl")]
149    pub store_url: Option<String>,
150
151    #[serde(rename = "storePlatform")]
152    pub store_platform: Option<String>,
153
154    #[serde(rename = "itadId")]
155    pub itad_id: Option<String>,
156
157    #[serde(rename = "currentPrice")]
158    pub current_price: Option<f64>,
159
160    #[serde(rename = "normalPrice")]
161    pub normal_price: Option<f64>,
162
163    #[serde(rename = "lowestPrice")]
164    pub lowest_price: Option<f64>,
165
166    #[serde(rename = "currency")]
167    pub currency: Option<String>,
168
169    #[serde(rename = "onSale")]
170    pub on_sale: bool,
171
172    pub voucher: Option<String>,
173
174    #[serde(rename = "addedAt")]
175    pub added_at: Option<String>,
176}