use std::sync::Arc;
use tokio::sync::RwLock;
use crate::protocol::{Message, Reply};
use crate::state::ServerState;
pub async fn handle_list(
server_state: Arc<RwLock<ServerState>>,
connection_id: u64,
params: Vec<String>,
) -> Result<Vec<Message>, Box<dyn std::error::Error>> {
let state = server_state.read().await;
let mut messages = Vec::new();
let requesting_connection = state.connections.get(&connection_id);
if requesting_connection.is_none() {
return Ok(messages);
}
let req_conn = requesting_connection.unwrap();
let requester_nick = req_conn.nickname.as_deref().unwrap_or("*");
let channel_filter = params.get(0).cloned();
let list_start_msg = Message::new("321")
.with_params(vec![
requester_nick.to_string(),
"Channel".to_string(),
"Users Name".to_string(),
]);
messages.push(list_start_msg);
if let Some(ref filter) = channel_filter {
let channel_names: Vec<&str> = filter.split(',').collect();
for channel_name in channel_names {
if let Some(channel) = state.channels.get(channel_name) {
let can_see = !channel.modes.contains(&'s') && !channel.modes.contains(&'p')
|| channel.is_member(connection_id);
if can_see {
let topic = channel.topic.as_deref().unwrap_or("");
let member_count = channel.member_count();
let list_msg = Message::new("322")
.with_params(vec![
requester_nick.to_string(),
channel_name.to_string(),
member_count.to_string(),
topic.to_string(),
]);
messages.push(list_msg);
}
}
}
} else {
for channel_entry in state.channels.iter() {
let (channel_name, channel) = channel_entry.pair();
let can_see = !channel.modes.contains(&'s') && !channel.modes.contains(&'p')
|| channel.is_member(connection_id);
if can_see {
let topic = channel.topic.as_deref().unwrap_or("");
let member_count = channel.member_count();
let list_msg = Message::new("322")
.with_params(vec![
requester_nick.to_string(),
channel_name.clone(),
member_count.to_string(),
topic.to_string(),
]);
messages.push(list_msg);
}
}
}
let list_end_msg = Message::new("323")
.with_params(vec![
requester_nick.to_string(),
"End of LIST".to_string(),
]);
messages.push(list_end_msg);
Ok(messages)
}
#[cfg(test)]
#[path = "list_test.rs"]
mod tests;