//! Trait definition for TdClient to enable dependency injection //! //! This trait allows tests to use FakeTdClient instead of real TDLib client. use crate::tdlib::{AuthState, FolderInfo, MessageInfo, ProfileInfo, UserCache, UserOnlineStatus}; use crate::types::{ChatId, MessageId, UserId}; use async_trait::async_trait; use std::path::PathBuf; use tdlib_rs::enums::{ChatAction, Update}; use super::ChatInfo; /// Trait for TDLib client operations /// /// This trait defines the interface for both real and fake TDLib clients, /// enabling dependency injection and easier testing. #[allow(dead_code)] #[async_trait] pub trait TdClientTrait: Send { // ============ Auth methods ============ async fn send_phone_number(&self, phone: String) -> Result<(), String>; async fn send_code(&self, code: String) -> Result<(), String>; async fn send_password(&self, password: String) -> Result<(), String>; // ============ Chat methods ============ async fn load_chats(&mut self, limit: i32) -> Result<(), String>; async fn load_folder_chats(&mut self, folder_id: i32, limit: i32) -> Result<(), String>; async fn leave_chat(&self, chat_id: ChatId) -> Result<(), String>; async fn get_profile_info(&self, chat_id: ChatId) -> Result; // ============ Chat actions ============ async fn send_chat_action(&self, chat_id: ChatId, action: ChatAction); fn clear_stale_typing_status(&mut self) -> bool; // ============ Message methods ============ async fn get_chat_history( &mut self, chat_id: ChatId, limit: i32, ) -> Result, String>; async fn load_older_messages( &mut self, chat_id: ChatId, from_message_id: MessageId, ) -> Result, String>; async fn get_pinned_messages(&mut self, chat_id: ChatId) -> Result, String>; async fn load_current_pinned_message(&mut self, chat_id: ChatId); async fn search_messages( &self, chat_id: ChatId, query: &str, ) -> Result, String>; async fn send_message( &mut self, chat_id: ChatId, text: String, reply_to_message_id: Option, reply_info: Option, ) -> Result; async fn edit_message( &mut self, chat_id: ChatId, message_id: MessageId, new_text: String, ) -> Result; async fn delete_messages( &mut self, chat_id: ChatId, message_ids: Vec, revoke: bool, ) -> Result<(), String>; async fn forward_messages( &mut self, to_chat_id: ChatId, from_chat_id: ChatId, message_ids: Vec, ) -> Result<(), String>; async fn set_draft_message(&self, chat_id: ChatId, text: String) -> Result<(), String>; fn push_message(&mut self, msg: MessageInfo); async fn fetch_missing_reply_info(&mut self); async fn process_pending_view_messages(&mut self); // ============ User methods ============ fn get_user_status_by_chat_id(&self, chat_id: ChatId) -> Option<&UserOnlineStatus>; async fn process_pending_user_ids(&mut self); // ============ Reaction methods ============ async fn get_message_available_reactions( &self, chat_id: ChatId, message_id: MessageId, ) -> Result, String>; async fn toggle_reaction( &self, chat_id: ChatId, message_id: MessageId, reaction: String, ) -> Result<(), String>; // ============ File methods ============ async fn download_file(&self, file_id: i32) -> Result; async fn download_voice_note(&self, file_id: i32) -> Result; // ============ Getters (immutable) ============ fn client_id(&self) -> i32; async fn get_me(&self) -> Result; fn auth_state(&self) -> &AuthState; fn chats(&self) -> &[ChatInfo]; fn folders(&self) -> &[FolderInfo]; fn current_chat_messages(&self) -> Vec; fn current_chat_id(&self) -> Option; fn current_pinned_message(&self) -> Option; fn typing_status(&self) -> Option<&(UserId, String, std::time::Instant)>; fn pending_view_messages(&self) -> &[(ChatId, Vec)]; fn pending_user_ids(&self) -> &[UserId]; fn main_chat_list_position(&self) -> i32; fn user_cache(&self) -> &UserCache; fn network_state(&self) -> super::types::NetworkState; // ============ Setters (mutable) ============ fn chats_mut(&mut self) -> &mut Vec; fn folders_mut(&mut self) -> &mut Vec; fn current_chat_messages_mut(&mut self) -> &mut Vec; fn clear_current_chat_messages(&mut self); fn set_current_chat_messages(&mut self, messages: Vec); fn set_current_chat_id(&mut self, chat_id: Option); fn set_current_pinned_message(&mut self, msg: Option); fn set_typing_status(&mut self, status: Option<(UserId, String, std::time::Instant)>); fn pending_view_messages_mut(&mut self) -> &mut Vec<(ChatId, Vec)>; fn pending_user_ids_mut(&mut self) -> &mut Vec; fn set_main_chat_list_position(&mut self, position: i32); fn user_cache_mut(&mut self) -> &mut UserCache; // ============ Notification methods ============ fn sync_notification_muted_chats(&mut self); // ============ Account switching ============ /// Recreates the client with a new database path (for account switching). /// /// For real TdClient: closes old client, creates new one, inits TDLib parameters. /// For FakeTdClient: no-op. async fn recreate_client(&mut self, db_path: PathBuf) -> Result<(), String>; // ============ Update handling ============ fn handle_update(&mut self, update: Update); }