refactor: implement trait-based DI for TdClient and fix stack overflow
Implement complete trait-based dependency injection pattern for TdClient to enable testing with FakeTdClient mock. Fix critical stack overflow bugs caused by infinite recursion in trait implementations. Breaking Changes: - App is now generic: App<T: TdClientTrait = TdClient> - All UI and input handlers are generic over TdClientTrait - TdClient methods now accessed through trait interface New Files: - src/tdlib/trait.rs: TdClientTrait definition with 40+ methods - src/tdlib/client_impl.rs: TdClientTrait impl for TdClient - tests/helpers/fake_tdclient_impl.rs: TdClientTrait impl for FakeTdClient Critical Fixes: - Fix stack overflow in send_message, edit_message, delete_messages - Fix stack overflow in forward_messages, current_chat_messages - Fix stack overflow in current_pinned_message - All methods now call message_manager directly to avoid recursion Testing: - FakeTdClient supports configurable auth_state for auth screen tests - Added pinned message support in FakeTdClient - All 196+ tests passing (188 tests + 8 benchmarks) Dependencies: - Added async-trait = "0.1" Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tele_tui::tdlib::{ChatInfo, MessageInfo, NetworkState, ProfileInfo, ReplyInfo};
|
||||
use tele_tui::tdlib::{AuthState, ChatInfo, MessageInfo, NetworkState, ProfileInfo, ReplyInfo};
|
||||
use tele_tui::tdlib::types::{FolderInfo, ReactionInfo};
|
||||
use tele_tui::types::{ChatId, MessageId, UserId};
|
||||
use tokio::sync::mpsc;
|
||||
@@ -35,6 +35,8 @@ pub struct FakeTdClient {
|
||||
pub network_state: Arc<Mutex<NetworkState>>,
|
||||
pub typing_chat_id: Arc<Mutex<Option<i64>>>,
|
||||
pub current_chat_id: Arc<Mutex<Option<i64>>>,
|
||||
pub current_pinned_message: Arc<Mutex<Option<MessageInfo>>>,
|
||||
pub auth_state: Arc<Mutex<AuthState>>,
|
||||
|
||||
// История действий (для проверки в тестах)
|
||||
pub sent_messages: Arc<Mutex<Vec<SentMessage>>>,
|
||||
@@ -108,6 +110,8 @@ impl Clone for FakeTdClient {
|
||||
network_state: Arc::clone(&self.network_state),
|
||||
typing_chat_id: Arc::clone(&self.typing_chat_id),
|
||||
current_chat_id: Arc::clone(&self.current_chat_id),
|
||||
current_pinned_message: Arc::clone(&self.current_pinned_message),
|
||||
auth_state: Arc::clone(&self.auth_state),
|
||||
sent_messages: Arc::clone(&self.sent_messages),
|
||||
edited_messages: Arc::clone(&self.edited_messages),
|
||||
deleted_messages: Arc::clone(&self.deleted_messages),
|
||||
@@ -138,6 +142,8 @@ impl FakeTdClient {
|
||||
network_state: Arc::new(Mutex::new(NetworkState::Ready)),
|
||||
typing_chat_id: Arc::new(Mutex::new(None)),
|
||||
current_chat_id: Arc::new(Mutex::new(None)),
|
||||
current_pinned_message: Arc::new(Mutex::new(None)),
|
||||
auth_state: Arc::new(Mutex::new(AuthState::Ready)),
|
||||
sent_messages: Arc::new(Mutex::new(vec![])),
|
||||
edited_messages: Arc::new(Mutex::new(vec![])),
|
||||
deleted_messages: Arc::new(Mutex::new(vec![])),
|
||||
@@ -221,6 +227,12 @@ impl FakeTdClient {
|
||||
*self.network_state.lock().unwrap() = state;
|
||||
self
|
||||
}
|
||||
|
||||
/// Установить состояние авторизации
|
||||
pub fn with_auth_state(self, state: AuthState) -> Self {
|
||||
*self.auth_state.lock().unwrap() = state;
|
||||
self
|
||||
}
|
||||
|
||||
/// Установить доступные реакции
|
||||
pub fn with_available_reactions(self, reactions: Vec<String>) -> Self {
|
||||
|
||||
Reference in New Issue
Block a user