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,6 +1,7 @@
// Chat state management - type-safe state machine for chat modes
use crate::tdlib::{MessageInfo, ProfileInfo};
use crate::types::MessageId;
/// Состояния чата - взаимоисключающие режимы работы с чатом
#[derive(Debug, Clone)]
@@ -17,7 +18,7 @@ pub enum ChatState {
/// Редактирование сообщения
Editing {
/// ID редактируемого сообщения
message_id: i64,
message_id: MessageId,
/// Индекс сообщения в списке
selected_index: usize,
},
@@ -25,13 +26,13 @@ pub enum ChatState {
/// Ответ на сообщение (reply)
Reply {
/// ID сообщения, на которое отвечаем
message_id: i64,
message_id: MessageId,
},
/// Пересылка сообщения (forward)
Forward {
/// ID сообщения для пересылки
message_id: i64,
message_id: MessageId,
/// Находимся в режиме выбора чата для пересылки
selecting_chat: bool,
},
@@ -39,13 +40,13 @@ pub enum ChatState {
/// Подтверждение удаления сообщения
DeleteConfirmation {
/// ID сообщения для удаления
message_id: i64,
message_id: MessageId,
},
/// Выбор реакции на сообщение
ReactionPicker {
/// ID сообщения для реакции
message_id: i64,
message_id: MessageId,
/// Список доступных реакций
available_reactions: Vec<String>,
/// Индекс выбранной реакции в picker
@@ -139,7 +140,7 @@ impl ChatState {
}
/// Возвращает ID выбранного сообщения (если есть)
pub fn selected_message_id(&self) -> Option<i64> {
pub fn selected_message_id(&self) -> Option<MessageId> {
match self {
ChatState::Editing { message_id, .. } => Some(*message_id),
ChatState::Reply { message_id } => Some(*message_id),

View File

@@ -5,6 +5,7 @@ pub use chat_state::ChatState;
pub use state::AppScreen;
use crate::tdlib::{ChatInfo, TdClient};
use crate::types::ChatId;
use ratatui::widgets::ListState;
pub struct App {
@@ -22,7 +23,7 @@ pub struct App {
// Main app state
pub chats: Vec<ChatInfo>,
pub chat_list_state: ListState,
pub selected_chat_id: Option<i64>,
pub selected_chat_id: Option<ChatId>,
pub message_input: String,
/// Позиция курсора в message_input (в символах)
pub cursor_position: usize,