refactor: complete nesting simplification (category 3 - 100%)
Simplified deep nesting across the codebase using modern Rust patterns:
let-else guards, early returns, iterator chains, and extracted functions.
**Files improved:**
1. src/tdlib/messages.rs (44 → 28 spaces max indent)
- fetch_missing_reply_info(): 7 → 2-3 levels
* Extracted fetch_and_update_reply()
* Used filter_map and iterator chains
- get_chat_history() retry loop: 6 → 3 levels
* Early continue for empty results
* Used .flatten() instead of nested if-let
2. src/input/main_input.rs (40 → 36 spaces max indent)
- handle_forward_mode(): 7 → 2-3 levels
* Extracted forward_selected_message()
- Reaction picker: 5 → 2-3 levels
* Extracted send_reaction()
- Scroll + load older: 6 → 2-3 levels
* Extracted load_older_messages_if_needed()
3. src/config.rs (36 → 32 spaces max indent)
- load_credentials(): 7 → 2-3 levels
* Extracted load_credentials_from_file()
* Extracted load_credentials_from_env()
* Used ? operator for Option chains
**Results:**
- Max nesting in entire project: ≤32 spaces (8 levels)
- 8 new functions extracted for better separation of concerns
- All 343 tests passing ✅
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -155,30 +155,32 @@ impl MessageManager {
|
||||
)
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(tdlib_rs::enums::Messages::Messages(messages_obj)) => {
|
||||
if !messages_obj.messages.is_empty() {
|
||||
all_messages.clear(); // Очищаем предыдущие результаты
|
||||
for msg_opt in messages_obj.messages.iter().rev() {
|
||||
if let Some(msg) = msg_opt {
|
||||
if let Some(info) = self.convert_message(msg).await {
|
||||
all_messages.push(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Если получили непустой результат, прекращаем попытки
|
||||
// (TDLib вернёт столько сообщений, сколько доступно, до limit)
|
||||
break;
|
||||
}
|
||||
|
||||
// Если сообщений мало, ждём перед следующей попыткой
|
||||
if attempt < max_attempts {
|
||||
sleep(Duration::from_millis(200)).await;
|
||||
}
|
||||
}
|
||||
let messages_obj = match result {
|
||||
Ok(tdlib_rs::enums::Messages::Messages(obj)) => obj,
|
||||
Err(e) => return Err(format!("Ошибка загрузки истории: {:?}", e)),
|
||||
};
|
||||
|
||||
// Skip empty results
|
||||
if messages_obj.messages.is_empty() {
|
||||
// Ждём перед следующей попыткой
|
||||
if attempt < max_attempts {
|
||||
sleep(Duration::from_millis(200)).await;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert messages using iterator chains (flatten removes None values)
|
||||
all_messages.clear(); // Очищаем предыдущие результаты
|
||||
|
||||
for msg in messages_obj.messages.iter().rev().flatten() {
|
||||
if let Some(info) = self.convert_message(msg).await {
|
||||
all_messages.push(info);
|
||||
}
|
||||
}
|
||||
|
||||
// Если получили непустой результат, прекращаем попытки
|
||||
// (TDLib вернёт столько сообщений, сколько доступно, до limit)
|
||||
break;
|
||||
}
|
||||
|
||||
Ok(all_messages)
|
||||
@@ -716,41 +718,60 @@ impl MessageManager {
|
||||
///
|
||||
/// Вызывайте после загрузки истории чата для заполнения информации о цитируемых сообщениях.
|
||||
pub async fn fetch_missing_reply_info(&mut self) {
|
||||
// Collect message IDs that need to be fetched
|
||||
let mut to_fetch = Vec::new();
|
||||
for msg in &self.current_chat_messages {
|
||||
if let Some(ref reply) = msg.interactions.reply_to {
|
||||
if reply.sender_name == "Unknown" {
|
||||
to_fetch.push(reply.message_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Early return if no chat selected
|
||||
let Some(chat_id) = self.current_chat_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Fetch missing messages
|
||||
if let Some(chat_id) = self.current_chat_id {
|
||||
for message_id in to_fetch {
|
||||
if let Ok(original_msg_enum) =
|
||||
functions::get_message(chat_id.as_i64(), message_id.as_i64(), self.client_id).await
|
||||
{
|
||||
let tdlib_rs::enums::Message::Message(original_msg) = original_msg_enum;
|
||||
if let Some(orig_info) = self.convert_message(&original_msg).await {
|
||||
// Update the reply info
|
||||
for msg in &mut self.current_chat_messages {
|
||||
if let Some(ref mut reply) = msg.interactions.reply_to {
|
||||
if reply.message_id == message_id {
|
||||
reply.sender_name = orig_info.metadata.sender_name.clone();
|
||||
reply.text = orig_info
|
||||
.content
|
||||
.text
|
||||
.chars()
|
||||
.take(50)
|
||||
.collect::<String>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Collect message IDs with missing reply info using filter_map
|
||||
let to_fetch: Vec<MessageId> = self
|
||||
.current_chat_messages
|
||||
.iter()
|
||||
.filter_map(|msg| {
|
||||
msg.interactions
|
||||
.reply_to
|
||||
.as_ref()
|
||||
.filter(|reply| reply.sender_name == "Unknown")
|
||||
.map(|reply| reply.message_id)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Fetch and update each missing message
|
||||
for message_id in to_fetch {
|
||||
self.fetch_and_update_reply(chat_id, message_id).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// Загружает одно сообщение и обновляет reply информацию.
|
||||
async fn fetch_and_update_reply(&mut self, chat_id: ChatId, message_id: MessageId) {
|
||||
// Try to fetch the original message
|
||||
let Ok(original_msg_enum) =
|
||||
functions::get_message(chat_id.as_i64(), message_id.as_i64(), self.client_id).await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let tdlib_rs::enums::Message::Message(original_msg) = original_msg_enum;
|
||||
let Some(orig_info) = self.convert_message(&original_msg).await else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Extract text preview (first 50 chars)
|
||||
let text_preview: String = orig_info
|
||||
.content
|
||||
.text
|
||||
.chars()
|
||||
.take(50)
|
||||
.collect();
|
||||
|
||||
// Update reply info in all messages that reference this message
|
||||
self.current_chat_messages
|
||||
.iter_mut()
|
||||
.filter_map(|msg| msg.interactions.reply_to.as_mut())
|
||||
.filter(|reply| reply.message_id == message_id)
|
||||
.for_each(|reply| {
|
||||
reply.sender_name = orig_info.metadata.sender_name.clone();
|
||||
reply.text = text_preview.clone();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user