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

@@ -6,6 +6,7 @@ use tele_tui::app::{App, AppScreen, ChatState};
use tele_tui::config::Config;
use tele_tui::tdlib::AuthState;
use tele_tui::tdlib::{ChatInfo, MessageInfo};
use tele_tui::types::{ChatId, MessageId};
/// Builder для создания тестового App
///
@@ -102,7 +103,7 @@ impl TestAppBuilder {
/// Режим редактирования сообщения
pub fn editing_message(mut self, message_id: i64, selected_index: usize) -> Self {
self.chat_state = Some(ChatState::Editing {
message_id,
message_id: MessageId::new(message_id),
selected_index,
});
self
@@ -110,14 +111,14 @@ impl TestAppBuilder {
/// Режим ответа на сообщение
pub fn replying_to(mut self, message_id: i64) -> Self {
self.chat_state = Some(ChatState::Reply { message_id });
self.chat_state = Some(ChatState::Reply { message_id: MessageId::new(message_id) });
self
}
/// Режим выбора реакции
pub fn reaction_picker(mut self, message_id: i64, available_reactions: Vec<String>) -> Self {
self.chat_state = Some(ChatState::ReactionPicker {
message_id,
message_id: MessageId::new(message_id),
available_reactions,
selected_index: 0,
});
@@ -136,7 +137,7 @@ impl TestAppBuilder {
/// Подтверждение удаления
pub fn delete_confirmation(mut self, message_id: i64) -> Self {
self.chat_state = Some(ChatState::DeleteConfirmation { message_id });
self.chat_state = Some(ChatState::DeleteConfirmation { message_id: MessageId::new(message_id) });
self
}
@@ -177,7 +178,7 @@ impl TestAppBuilder {
/// Режим пересылки сообщения
pub fn forward_mode(mut self, message_id: i64) -> Self {
self.chat_state = Some(ChatState::Forward {
message_id,
message_id: MessageId::new(message_id),
selecting_chat: true,
});
self
@@ -223,7 +224,7 @@ impl TestAppBuilder {
app.screen = self.screen;
app.chats = self.chats;
app.selected_chat_id = self.selected_chat_id;
app.selected_chat_id = self.selected_chat_id.map(ChatId::new);
app.message_input = self.message_input;
app.is_searching = self.is_searching;
app.search_query = self.search_query;
@@ -264,7 +265,7 @@ impl TestAppBuilder {
if let Some(chat_id) = self.selected_chat_id {
if let Some(messages) = self.messages.get(&chat_id) {
app.td_client.message_manager.current_chat_messages = messages.clone();
app.td_client.set_current_chat_id(Some(chat_id));
app.td_client.set_current_chat_id(Some(ChatId::new(chat_id)));
}
}