refactor: resolve all lint findings

- remove 34 trivial restating comments (auto-fix)
- replace all 20 production .unwrap() calls with graceful handling:
  ?-propagation via LockPoisoned, unwrap_or_default on infallible
  conversions, let _ = on actor-channel sends, and a downloads_sender()
  helper in the TUI that also dedupes three channel-init blocks
- collapse nested if into match guard (clippy::collapsible_match)
- split client.rs (2275 lines) into a client/ module: connection,
  search, downloads, uploads, rooms, operations
- split ui/main_tui.rs (2027 lines) into a main_tui/ module: render,
  input, browse, rooms, downloads, search
- extract oversized functions: peer_actor/server_actor handle_message
  into per-message helpers, main() into init_logging/run_default_tui,
  download_selector and main_tui render into per-section helpers

Mechanical only, zero behavior change. Verified: clippy clean
(pedantic+nursery), fmt clean, 143 unit tests + 16 e2e tests against
soulfind pass, lint clean.
This commit is contained in:
Michel de Graaf
2026-07-20 10:53:57 +02:00
parent 17864ac9b0
commit 2918b0ce75
35 changed files with 4113 additions and 3983 deletions
-2
View File
@@ -74,7 +74,6 @@ impl ActorSystem {
let (sender, receiver) = channel::<ActorMessage<A::Message>>();
let handle = ActorHandle { sender };
// Start the actor event loop on the thread pool
self.thread_pool.execute(move || {
actor.on_start();
Self::run_actor_loop(&mut actor, receiver);
@@ -198,7 +197,6 @@ mod tests {
assert_eq!(count.load(Ordering::SeqCst), 6);
// Stop the actor
handle.stop().unwrap();
// Give actor time to process the stop message
+189 -154
View File
@@ -199,130 +199,23 @@ impl PeerActor {
self.send_message(message);
}
PeerMessage::FileSearchResult(file_search) => {
if let Err(e) = self
.client_channel
.send(ClientOperation::SearchResult(file_search))
{
error!(
"[peer:{}] failed to forward search result: {}",
self.peer_username(),
e
);
}
self.handle_file_search_result(file_search);
}
PeerMessage::TransferRequest(transfer) => {
let username = self.peer_username();
debug!(
"[peer:{}] TransferRequest for {}",
username, transfer.token
);
if let Err(e) = self.client_channel.send(
ClientOperation::UpdateDownloadTokens(
transfer.clone(),
username.clone(),
),
) {
error!(
"[peer:{}] failed to send UpdateDownloadTokens: {}",
username, e
);
}
let transfer_response =
MessageFactory::build_transfer_response_message(transfer);
if let Some(ref handle) = self.self_handle
&& let Err(e) =
handle.send(PeerMessage::SendMessage(transfer_response))
{
error!(
"[peer:{}] Failed to send TransferResponse message: {}",
username, e
);
}
self.handle_transfer_request(transfer);
}
PeerMessage::TransferResponse {
token,
allowed,
reason,
} => {
let username = self.peer_username();
debug!(
"[peer:{}] transfer response token: {} allowed: {}",
username, token, allowed
);
// If this token is one of our uploads, the peer just accepted
// our offer — start streaming. This leaves the download path
// (every other token) byte-for-byte unchanged.
if self.serving_tokens.remove(&token) {
if allowed {
let _ = self
.client_channel
.send(ClientOperation::StartUpload { token });
}
return;
}
if allowed {
debug!(
"[peer:{}] Transfer allowed, ready to connect with token {:}",
username, token
);
let Some(peer_snapshot) = self.peer_snapshot() else {
return;
};
if let Err(e) = self.client_channel.send(
ClientOperation::DownloadFromPeer(
token,
peer_snapshot,
allowed,
),
) {
error!(
"[peer:{}] failed to send DownloadFromPeer: {}",
username, e
);
}
} else if let Some(reason_text) = reason {
debug!(
"[peer:{}] Transfer rejected: {} - token {}, waiting for TransferRequest...",
username, reason_text, token
);
}
self.handle_transfer_response(token, allowed, reason);
}
PeerMessage::PlaceInQueueResponse { filename, place } => {
let username = self.peer_username();
debug!(
"[peer:{}] Place in queue response - file: {}, place: {}",
username, filename, place
);
if let Err(e) = self.client_channel.send(
ClientOperation::PlaceInQueueUpdate {
username: username.clone(),
filename,
place,
},
) {
error!(
"[peer:{}] failed to forward PlaceInQueueUpdate: {}",
username, e
);
}
self.handle_place_in_queue_response(filename, place);
}
PeerMessage::SetUsername(username) => {
trace!(
"[peer:{}] SetUsername: {}",
self.peer_username(),
username
);
match self.peer.write_safe() {
Ok(mut p) => p.username = username,
Err(e) => {
error!("[peer_actor] SetUsername write: {}", e);
}
}
self.handle_set_username(username);
}
PeerMessage::QueueUpload(filename) => {
let message =
@@ -330,48 +223,20 @@ impl PeerActor {
self.send_message(message);
}
PeerMessage::IncomingQueueUpload(filename) => {
// A peer wants to download one of our shared files. Ask the
// client (which owns the shares) to prepare the upload.
let requester_key = self.peer_username();
if let Err(e) =
self.client_channel.send(ClientOperation::QueueUpload {
requester_key,
filename,
})
{
error!("[peer_actor] forward IncomingQueueUpload: {}", e);
}
self.handle_incoming_queue_upload(filename);
}
PeerMessage::ServeUpload {
token,
filename,
size,
} => {
self.serving_tokens.insert(token);
let message = MessageFactory::build_upload_transfer_request(
&filename, token, size,
);
self.send_message(message);
self.handle_serve_upload(token, filename, size);
}
PeerMessage::ShareListRequested => {
let requester_key = self.peer_username();
if let Err(e) = self
.client_channel
.send(ClientOperation::ShareListRequested { requester_key })
{
error!("[peer_actor] forward ShareListRequested: {}", e);
}
self.handle_share_list_requested();
}
PeerMessage::ShareListReceived(directories) => {
let username = self.peer_username();
if let Err(e) =
self.client_channel.send(ClientOperation::BrowseResult {
username,
directories,
})
{
error!("[peer_actor] forward BrowseResult: {}", e);
}
self.handle_share_list_received(directories);
}
PeerMessage::RequestTransfer(download) => {
let message = MessageFactory::build_transfer_request_message(
@@ -384,19 +249,189 @@ impl PeerActor {
self.process_read();
}
PeerMessage::UploadFailed(username, filename) => {
if let Err(e) = self
.client_channel
.send(ClientOperation::UploadFailed(username, filename))
{
error!(
"[peer_actor] failed to forward UploadFailed: {}",
e
);
}
self.handle_upload_failed(username, filename);
}
}
}
fn handle_file_search_result(&self, file_search: SearchResult) {
if let Err(e) = self
.client_channel
.send(ClientOperation::SearchResult(file_search))
{
error!(
"[peer:{}] failed to forward search result: {}",
self.peer_username(),
e
);
}
}
fn handle_transfer_request(&self, transfer: Transfer) {
let username = self.peer_username();
debug!("[peer:{}] TransferRequest for {}", username, transfer.token);
if let Err(e) =
self.client_channel
.send(ClientOperation::UpdateDownloadTokens(
transfer.clone(),
username.clone(),
))
{
error!(
"[peer:{}] failed to send UpdateDownloadTokens: {}",
username, e
);
}
let transfer_response =
MessageFactory::build_transfer_response_message(transfer);
if let Some(ref handle) = self.self_handle
&& let Err(e) =
handle.send(PeerMessage::SendMessage(transfer_response))
{
error!(
"[peer:{}] Failed to send TransferResponse message: {}",
username, e
);
}
}
fn handle_transfer_response(
&mut self,
token: u32,
allowed: bool,
reason: Option<String>,
) {
let username = self.peer_username();
debug!(
"[peer:{}] transfer response token: {} allowed: {}",
username, token, allowed
);
// If this token is one of our uploads, the peer just accepted
// our offer — start streaming. This leaves the download path
// (every other token) byte-for-byte unchanged.
if self.serving_tokens.remove(&token) {
if allowed {
let _ = self
.client_channel
.send(ClientOperation::StartUpload { token });
}
return;
}
if allowed {
debug!(
"[peer:{}] Transfer allowed, ready to connect with token {:}",
username, token
);
let Some(peer_snapshot) = self.peer_snapshot() else {
return;
};
if let Err(e) =
self.client_channel.send(ClientOperation::DownloadFromPeer(
token,
peer_snapshot,
allowed,
))
{
error!(
"[peer:{}] failed to send DownloadFromPeer: {}",
username, e
);
}
} else if let Some(reason_text) = reason {
debug!(
"[peer:{}] Transfer rejected: {} - token {}, waiting for TransferRequest...",
username, reason_text, token
);
}
}
fn handle_place_in_queue_response(&self, filename: String, place: u32) {
let username = self.peer_username();
debug!(
"[peer:{}] Place in queue response - file: {}, place: {}",
username, filename, place
);
if let Err(e) =
self.client_channel
.send(ClientOperation::PlaceInQueueUpdate {
username: username.clone(),
filename,
place,
})
{
error!(
"[peer:{}] failed to forward PlaceInQueueUpdate: {}",
username, e
);
}
}
fn handle_set_username(&self, username: String) {
trace!("[peer:{}] SetUsername: {}", self.peer_username(), username);
match self.peer.write_safe() {
Ok(mut p) => p.username = username,
Err(e) => {
error!("[peer_actor] SetUsername write: {}", e);
}
}
}
fn handle_incoming_queue_upload(&self, filename: String) {
// A peer wants to download one of our shared files. Ask the
// client (which owns the shares) to prepare the upload.
let requester_key = self.peer_username();
if let Err(e) = self.client_channel.send(ClientOperation::QueueUpload {
requester_key,
filename,
}) {
error!("[peer_actor] forward IncomingQueueUpload: {}", e);
}
}
fn handle_serve_upload(&mut self, token: u32, filename: String, size: u64) {
self.serving_tokens.insert(token);
let message = MessageFactory::build_upload_transfer_request(
&filename, token, size,
);
self.send_message(message);
}
fn handle_share_list_requested(&self) {
let requester_key = self.peer_username();
if let Err(e) = self
.client_channel
.send(ClientOperation::ShareListRequested { requester_key })
{
error!("[peer_actor] forward ShareListRequested: {}", e);
}
}
fn handle_share_list_received(&self, directories: Vec<SharedDirectory>) {
let username = self.peer_username();
if let Err(e) =
self.client_channel.send(ClientOperation::BrowseResult {
username,
directories,
})
{
error!("[peer_actor] forward BrowseResult: {}", e);
}
}
fn handle_upload_failed(&self, username: String, filename: String) {
if let Err(e) = self
.client_channel
.send(ClientOperation::UploadFailed(username, filename))
{
error!("[peer_actor] failed to forward UploadFailed: {}", e);
}
}
fn process_read(&mut self) {
if self.reader.buffer_len() > 0 {
self.extract_and_process_messages();
@@ -489,7 +524,7 @@ impl PeerActor {
.get_message_name(
MessageType::Peer,
u32::from_le_bytes(
message.get_slice(0, 4).try_into().unwrap()
message.get_slice(0, 4).try_into().unwrap_or_default()
)
)
.map_err(|e| e.to_string())
+150 -105
View File
@@ -413,37 +413,10 @@ impl ServerActor {
match msg {
ServerMessage::ConnectToPeer(peer) => {
if let Some(op) = match peer.connection_type {
ConnectionType::P | ConnectionType::F => {
Some(ClientOperation::ConnectToPeer(peer))
}
ConnectionType::D => None,
} && let Err(e) = self.client_channel.send(op)
{
error!("[server] failed to send ConnectToPeer: {}", e);
}
self.handle_connect_to_peer(peer);
}
ServerMessage::LoginStatus(message) => {
match self.context.write_safe() {
Ok(mut ctx) => ctx.logged_in = Some(message),
Err(e) => {
error!("[server] LoginStatus write: {}", e);
}
}
// Send the post-login handshake exactly once, only on success,
// on the live path (the old ServerActor::login did this but was
// never called). Advertises real shared counts and, when
// listening, the port peers must connect to.
if message {
for msg in post_login_messages(
self.enable_listen,
self.listen_port,
self.shared_folder_count,
self.shared_file_count,
) {
self.send_message(msg);
}
}
self.handle_login_status(message);
}
ServerMessage::PierceFirewall(token) => {
self.send_message(
@@ -465,40 +438,16 @@ impl ServerActor {
obfuscation_type,
obfuscated_port,
} => {
debug!(
"[server] Received GetPeerAddress response for {}: {}:{} (obf_type: {}, obf_port: {})",
username, host, port, obfuscation_type, obfuscated_port
self.handle_get_peer_address_response(
username,
host,
port,
obfuscation_type,
obfuscated_port,
);
if let Err(e) = self.client_channel.send(
ClientOperation::GetPeerAddressResponse {
username,
host,
port,
obfuscation_type,
obfuscated_port,
},
) {
error!(
"[server] Error forwarding GetPeerAddress response to client: {}",
e
);
}
}
ServerMessage::PrivateMessageReceived(user_message) => {
debug!(
"[server] Private message from {}",
user_message.username()
);
if let Err(e) = self
.client_channel
.send(ClientOperation::PrivateMessageReceived(user_message))
{
error!(
"[server] Error forwarding private message to client: {}",
e
);
}
self.handle_private_message_received(user_message);
}
ServerMessage::RoomListReceived(rooms) => {
self.forward_room_event(RoomEvent::List(rooms));
@@ -537,41 +486,7 @@ impl ServerActor {
password,
response,
} => {
self.queue_message(MessageFactory::build_login_message(
&username, &password,
));
let start = std::time::Instant::now();
let timeout = Duration::from_secs(5);
let context = self.context.clone();
std::thread::spawn(move || {
loop {
if start.elapsed() >= timeout {
let _ = response.send(Err(SoulseekRs::Timeout));
break;
}
let logged_in = match context.read_safe() {
Ok(ctx) => ctx.logged_in,
Err(e) => {
let _ = response.send(Err(e));
break;
}
};
if let Some(logged_in) = logged_in {
let result = if logged_in {
Ok(true)
} else {
Err(SoulseekRs::AuthenticationFailed)
};
let _ = response.send(result);
break;
}
std::thread::sleep(Duration::from_millis(100));
}
});
self.handle_login(username, password, response);
}
ServerMessage::FileSearch { token, query } => {
self.file_search(token, &query);
@@ -581,19 +496,149 @@ impl ServerActor {
token,
query,
} => {
if let Err(e) =
self.client_channel.send(ClientOperation::IncomingSearch {
username,
token,
query,
})
{
error!("[server] forward IncomingSearch: {}", e);
}
self.handle_file_search_request(username, token, query);
}
}
}
fn handle_connect_to_peer(&self, peer: Peer) {
if let Some(op) = match peer.connection_type {
ConnectionType::P | ConnectionType::F => {
Some(ClientOperation::ConnectToPeer(peer))
}
ConnectionType::D => None,
} && let Err(e) = self.client_channel.send(op)
{
error!("[server] failed to send ConnectToPeer: {}", e);
}
}
fn handle_login_status(&mut self, message: bool) {
match self.context.write_safe() {
Ok(mut ctx) => ctx.logged_in = Some(message),
Err(e) => {
error!("[server] LoginStatus write: {}", e);
}
}
// Send the post-login handshake exactly once, only on success,
// on the live path (the old ServerActor::login did this but was
// never called). Advertises real shared counts and, when
// listening, the port peers must connect to.
if message {
for msg in post_login_messages(
self.enable_listen,
self.listen_port,
self.shared_folder_count,
self.shared_file_count,
) {
self.send_message(msg);
}
}
}
fn handle_get_peer_address_response(
&self,
username: String,
host: String,
port: u32,
obfuscation_type: u32,
obfuscated_port: u16,
) {
debug!(
"[server] Received GetPeerAddress response for {}: {}:{} (obf_type: {}, obf_port: {})",
username, host, port, obfuscation_type, obfuscated_port
);
if let Err(e) =
self.client_channel
.send(ClientOperation::GetPeerAddressResponse {
username,
host,
port,
obfuscation_type,
obfuscated_port,
})
{
error!(
"[server] Error forwarding GetPeerAddress response to client: {}",
e
);
}
}
fn handle_private_message_received(&self, user_message: UserMessage) {
debug!("[server] Private message from {}", user_message.username());
if let Err(e) = self
.client_channel
.send(ClientOperation::PrivateMessageReceived(user_message))
{
error!(
"[server] Error forwarding private message to client: {}",
e
);
}
}
fn handle_login(
&mut self,
username: String,
password: String,
response: std::sync::mpsc::Sender<Result<bool, SoulseekRs>>,
) {
self.queue_message(MessageFactory::build_login_message(
&username, &password,
));
let start = std::time::Instant::now();
let timeout = Duration::from_secs(5);
let context = self.context.clone();
std::thread::spawn(move || {
loop {
if start.elapsed() >= timeout {
let _ = response.send(Err(SoulseekRs::Timeout));
break;
}
let logged_in = match context.read_safe() {
Ok(ctx) => ctx.logged_in,
Err(e) => {
let _ = response.send(Err(e));
break;
}
};
if let Some(logged_in) = logged_in {
let result = if logged_in {
Ok(true)
} else {
Err(SoulseekRs::AuthenticationFailed)
};
let _ = response.send(result);
break;
}
std::thread::sleep(Duration::from_millis(100));
}
});
}
fn handle_file_search_request(
&self,
username: String,
token: u32,
query: String,
) {
if let Err(e) =
self.client_channel.send(ClientOperation::IncomingSearch {
username,
token,
query,
})
{
error!("[server] forward IncomingSearch: {}", e);
}
}
fn process_read(&mut self) {
if self.reader.buffer_len() > 0 {
self.extract_and_process_messages();
@@ -696,7 +741,7 @@ impl ServerActor {
.get_message_name(
MessageType::Server,
u32::from_le_bytes(
message.get_slice(0, 4).try_into().unwrap()
message.get_slice(0, 4).try_into().unwrap_or_default()
)
)
.map_err(|e| e.to_string())