refactor: implement newtype pattern for IDs (P2.4)

Добавлены типобезопасные обёртки ChatId, MessageId, UserId для предотвращения
смешивания разных типов идентификаторов на этапе компиляции.

Изменения:
- Создан src/types.rs с тремя newtype структурами
- Реализованы методы: new(), as_i64(), From<i64>, Display
- Добавлены traits: Hash, Eq, Serialize, Deserialize
- Обновлены 15+ модулей для использования новых типов:
  * tdlib: types.rs, chats.rs, messages.rs, users.rs, reactions.rs, client.rs
  * app: mod.rs, chat_state.rs
  * input: main_input.rs
  * tests: app_builder.rs, test_data.rs
- Исправлены 53 ошибки компиляции связанные с type conversions

Преимущества:
- Компилятор предотвращает смешивание разных типов ID
- Улучшенная читаемость кода (явные типы вместо i64)
- Самодокументирующиеся типы

Статус: Priority 2 теперь 60% (3/5 задач)
-  Error enum
-  Config validation
-  Newtype для ID
-  MessageInfo реструктуризация
-  MessageBuilder pattern

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Kilin
2026-01-31 01:33:18 +03:00
parent 38e73befc1
commit 7081a886ad
15 changed files with 458 additions and 177 deletions

View File

@@ -1,5 +1,6 @@
use crate::app::App;
use crate::tdlib::ChatAction;
use crate::types::{ChatId, MessageId};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use std::time::{Duration, Instant};
use tokio::time::timeout;
@@ -187,6 +188,7 @@ pub async fn handle(app: &mut App, key: KeyEvent) {
KeyCode::Enter => {
// Перейти к выбранному сообщению
if let Some(msg_id) = app.get_selected_search_result_id() {
let msg_id = MessageId::new(msg_id);
let msg_index = app
.td_client
.current_chat_messages()
@@ -260,6 +262,7 @@ pub async fn handle(app: &mut App, key: KeyEvent) {
KeyCode::Enter => {
// Перейти к сообщению в истории
if let Some(msg_id) = app.get_selected_pinned_id() {
let msg_id = MessageId::new(msg_id);
// Ищем индекс сообщения в текущей истории
let msg_index = app
.td_client
@@ -324,6 +327,7 @@ pub async fn handle(app: &mut App, key: KeyEvent) {
if let Some(emoji) = app.get_selected_reaction().cloned() {
if let Some(message_id) = app.get_selected_message_for_reaction() {
if let Some(chat_id) = app.selected_chat_id {
let message_id = MessageId::new(message_id);
app.status_message = Some("Отправка реакции...".to_string());
app.needs_redraw = true;