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:
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Test data builders and fixtures
|
||||
|
||||
use tele_tui::tdlib::{ChatInfo, ForwardInfo, MessageInfo, ProfileInfo, ReactionInfo, ReplyInfo};
|
||||
use tele_tui::types::{ChatId, MessageId};
|
||||
|
||||
/// Builder для создания тестового чата
|
||||
pub struct TestChatBuilder {
|
||||
@@ -80,7 +81,7 @@ impl TestChatBuilder {
|
||||
|
||||
pub fn build(self) -> ChatInfo {
|
||||
ChatInfo {
|
||||
id: self.id,
|
||||
id: ChatId::new(self.id),
|
||||
title: self.title,
|
||||
username: self.username,
|
||||
last_message: self.last_message,
|
||||
@@ -89,7 +90,7 @@ impl TestChatBuilder {
|
||||
unread_mention_count: self.unread_mention_count,
|
||||
is_pinned: self.is_pinned,
|
||||
order: self.order,
|
||||
last_read_outbox_message_id: self.last_read_outbox_message_id,
|
||||
last_read_outbox_message_id: MessageId::new(self.last_read_outbox_message_id),
|
||||
folder_ids: self.folder_ids,
|
||||
is_muted: self.is_muted,
|
||||
draft_text: self.draft_text,
|
||||
@@ -165,7 +166,7 @@ impl TestMessageBuilder {
|
||||
|
||||
pub fn reply_to(mut self, message_id: i64, sender: &str, text: &str) -> Self {
|
||||
self.reply_to = Some(ReplyInfo {
|
||||
message_id,
|
||||
message_id: MessageId::new(message_id),
|
||||
sender_name: sender.to_string(),
|
||||
text: text.to_string(),
|
||||
});
|
||||
@@ -188,7 +189,7 @@ impl TestMessageBuilder {
|
||||
|
||||
pub fn build(self) -> MessageInfo {
|
||||
MessageInfo {
|
||||
id: self.id,
|
||||
id: MessageId::new(self.id),
|
||||
sender_name: self.sender_name,
|
||||
is_outgoing: self.is_outgoing,
|
||||
content: self.content,
|
||||
@@ -223,7 +224,7 @@ pub fn create_test_user(name: &str, id: i64) -> (i64, String) {
|
||||
/// Хелпер для создания профиля
|
||||
pub fn create_test_profile(title: &str, chat_id: i64) -> ProfileInfo {
|
||||
ProfileInfo {
|
||||
chat_id,
|
||||
chat_id: ChatId::new(chat_id),
|
||||
title: title.to_string(),
|
||||
username: None,
|
||||
bio: None,
|
||||
|
||||
Reference in New Issue
Block a user