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:
@@ -1,4 +1,5 @@
|
||||
use crate::constants::{MAX_MESSAGES_IN_CHAT, TDLIB_MESSAGE_LIMIT};
|
||||
use crate::types::{ChatId, MessageId};
|
||||
use tdlib_rs::enums::{ChatAction, InputMessageContent, InputMessageReplyTo, MessageContent, MessageSender, SearchMessagesFilter, TextParseMode};
|
||||
use tdlib_rs::functions;
|
||||
use tdlib_rs::types::{Chat as TdChat, FormattedText, InputMessageReplyToMessage, InputMessageText, Message as TdMessage, TextEntity, TextParseModeMarkdown};
|
||||
@@ -8,10 +9,10 @@ use super::types::{ForwardInfo, MessageInfo, ReactionInfo, ReplyInfo};
|
||||
/// Менеджер сообщений
|
||||
pub struct MessageManager {
|
||||
pub current_chat_messages: Vec<MessageInfo>,
|
||||
pub current_chat_id: Option<i64>,
|
||||
pub current_chat_id: Option<ChatId>,
|
||||
pub current_pinned_message: Option<MessageInfo>,
|
||||
/// Очередь сообщений для отметки как прочитанных: (chat_id, message_ids)
|
||||
pub pending_view_messages: Vec<(i64, Vec<i64>)>,
|
||||
pub pending_view_messages: Vec<(ChatId, Vec<MessageId>)>,
|
||||
client_id: i32,
|
||||
}
|
||||
|
||||
@@ -39,14 +40,14 @@ impl MessageManager {
|
||||
/// Получить историю чата
|
||||
pub async fn get_chat_history(
|
||||
&mut self,
|
||||
chat_id: i64,
|
||||
chat_id: ChatId,
|
||||
limit: i32,
|
||||
) -> Result<Vec<MessageInfo>, String> {
|
||||
// Устанавливаем текущий чат для получения новых сообщений
|
||||
self.current_chat_id = Some(chat_id);
|
||||
|
||||
let result = functions::get_chat_history(
|
||||
chat_id,
|
||||
chat_id.as_i64(),
|
||||
0, // from_message_id
|
||||
0, // offset
|
||||
limit,
|
||||
@@ -75,12 +76,12 @@ impl MessageManager {
|
||||
/// Загрузить более старые сообщения
|
||||
pub async fn load_older_messages(
|
||||
&mut self,
|
||||
chat_id: i64,
|
||||
from_message_id: i64,
|
||||
chat_id: ChatId,
|
||||
from_message_id: MessageId,
|
||||
) -> Result<Vec<MessageInfo>, String> {
|
||||
let result = functions::get_chat_history(
|
||||
chat_id,
|
||||
from_message_id,
|
||||
chat_id.as_i64(),
|
||||
from_message_id.as_i64(),
|
||||
0, // offset
|
||||
TDLIB_MESSAGE_LIMIT,
|
||||
false,
|
||||
@@ -106,9 +107,9 @@ impl MessageManager {
|
||||
}
|
||||
|
||||
/// Получить закреплённые сообщения
|
||||
pub async fn get_pinned_messages(&mut self, chat_id: i64) -> Result<Vec<MessageInfo>, String> {
|
||||
pub async fn get_pinned_messages(&mut self, chat_id: ChatId) -> Result<Vec<MessageInfo>, String> {
|
||||
let result = functions::search_chat_messages(
|
||||
chat_id,
|
||||
chat_id.as_i64(),
|
||||
String::new(),
|
||||
None,
|
||||
0, // from_message_id
|
||||
@@ -137,7 +138,7 @@ impl MessageManager {
|
||||
}
|
||||
|
||||
/// Загрузить текущее закреплённое сообщение
|
||||
pub async fn load_current_pinned_message(&mut self, chat_id: i64) {
|
||||
pub async fn load_current_pinned_message(&mut self, chat_id: ChatId) {
|
||||
// TODO: В tdlib-rs 1.8.29 поле pinned_message_id было удалено из Chat.
|
||||
// Нужно использовать getChatPinnedMessage или альтернативный способ.
|
||||
// Временно отключено.
|
||||
@@ -155,11 +156,11 @@ impl MessageManager {
|
||||
/// Поиск сообщений в чате
|
||||
pub async fn search_messages(
|
||||
&self,
|
||||
chat_id: i64,
|
||||
chat_id: ChatId,
|
||||
query: &str,
|
||||
) -> Result<Vec<MessageInfo>, String> {
|
||||
let result = functions::search_chat_messages(
|
||||
chat_id,
|
||||
chat_id.as_i64(),
|
||||
query.to_string(),
|
||||
None,
|
||||
0, // from_message_id
|
||||
@@ -190,9 +191,9 @@ impl MessageManager {
|
||||
/// Отправить сообщение
|
||||
pub async fn send_message(
|
||||
&self,
|
||||
chat_id: i64,
|
||||
chat_id: ChatId,
|
||||
text: String,
|
||||
reply_to_message_id: Option<i64>,
|
||||
reply_to_message_id: Option<MessageId>,
|
||||
_reply_info: Option<ReplyInfo>,
|
||||
) -> Result<MessageInfo, String> {
|
||||
// Парсим markdown в тексте
|
||||
@@ -224,13 +225,13 @@ impl MessageManager {
|
||||
let reply_to = reply_to_message_id.map(|msg_id| {
|
||||
InputMessageReplyTo::Message(InputMessageReplyToMessage {
|
||||
chat_id: 0,
|
||||
message_id: msg_id,
|
||||
message_id: msg_id.as_i64(),
|
||||
quote: None,
|
||||
})
|
||||
});
|
||||
|
||||
let result = functions::send_message(
|
||||
chat_id,
|
||||
chat_id.as_i64(),
|
||||
0, // message_thread_id
|
||||
reply_to,
|
||||
None, // options
|
||||
@@ -252,8 +253,8 @@ impl MessageManager {
|
||||
/// Редактировать сообщение
|
||||
pub async fn edit_message(
|
||||
&self,
|
||||
chat_id: i64,
|
||||
message_id: i64,
|
||||
chat_id: ChatId,
|
||||
message_id: MessageId,
|
||||
text: String,
|
||||
) -> Result<MessageInfo, String> {
|
||||
let formatted_text = match functions::parse_text_entities(
|
||||
@@ -282,7 +283,7 @@ impl MessageManager {
|
||||
});
|
||||
|
||||
let result =
|
||||
functions::edit_message_text(chat_id, message_id, content, self.client_id).await;
|
||||
functions::edit_message_text(chat_id.as_i64(), message_id.as_i64(), content, self.client_id).await;
|
||||
|
||||
match result {
|
||||
Ok(tdlib_rs::enums::Message::Message(msg)) => self
|
||||
@@ -297,12 +298,13 @@ impl MessageManager {
|
||||
/// Удалить сообщения
|
||||
pub async fn delete_messages(
|
||||
&self,
|
||||
chat_id: i64,
|
||||
message_ids: Vec<i64>,
|
||||
chat_id: ChatId,
|
||||
message_ids: Vec<MessageId>,
|
||||
revoke: bool,
|
||||
) -> Result<(), String> {
|
||||
let message_ids_i64: Vec<i64> = message_ids.into_iter().map(|id| id.as_i64()).collect();
|
||||
let result =
|
||||
functions::delete_messages(chat_id, message_ids, revoke, self.client_id).await;
|
||||
functions::delete_messages(chat_id.as_i64(), message_ids_i64, revoke, self.client_id).await;
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(format!("Ошибка удаления: {:?}", e)),
|
||||
@@ -312,15 +314,16 @@ impl MessageManager {
|
||||
/// Переслать сообщения
|
||||
pub async fn forward_messages(
|
||||
&self,
|
||||
to_chat_id: i64,
|
||||
from_chat_id: i64,
|
||||
message_ids: Vec<i64>,
|
||||
to_chat_id: ChatId,
|
||||
from_chat_id: ChatId,
|
||||
message_ids: Vec<MessageId>,
|
||||
) -> Result<(), String> {
|
||||
let message_ids_i64: Vec<i64> = message_ids.into_iter().map(|id| id.as_i64()).collect();
|
||||
let result = functions::forward_messages(
|
||||
to_chat_id,
|
||||
to_chat_id.as_i64(),
|
||||
0, // message_thread_id
|
||||
from_chat_id,
|
||||
message_ids,
|
||||
from_chat_id.as_i64(),
|
||||
message_ids_i64,
|
||||
None, // options
|
||||
false, // send_copy
|
||||
false, // remove_caption
|
||||
@@ -335,7 +338,7 @@ impl MessageManager {
|
||||
}
|
||||
|
||||
/// Установить черновик
|
||||
pub async fn set_draft_message(&self, chat_id: i64, text: String) -> Result<(), String> {
|
||||
pub async fn set_draft_message(&self, chat_id: ChatId, text: String) -> Result<(), String> {
|
||||
use tdlib_rs::types::DraftMessage;
|
||||
|
||||
let draft = if text.is_empty() {
|
||||
@@ -355,7 +358,7 @@ impl MessageManager {
|
||||
})
|
||||
};
|
||||
|
||||
let result = functions::set_chat_draft_message(chat_id, 0, draft, self.client_id).await;
|
||||
let result = functions::set_chat_draft_message(chat_id.as_i64(), 0, draft, self.client_id).await;
|
||||
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
|
||||
Reference in New Issue
Block a user