use anyhow::{bail, Context as AnyhowContext}; use solstice_proto::server::{PeerAddressRequest, ServerRequest}; use crate::context::Context; use crate::message_handler::MessageHandler; use crate::peer::PeerState; #[derive(Debug, Default)] pub struct PeerConnectRequestHandler; impl MessageHandler for PeerConnectRequestHandler { type Message = String; fn run( self, context: &mut Context, user_name: &String, ) -> anyhow::Result<()> { let peer = match context.state.peers.peers.get_mut(user_name) { Some(peer) => peer, None => { // Address is not even known, we need to ask for it first. context .state .peers .peers .insert(user_name.clone(), PeerState::FetchingAddress); let request = ServerRequest::PeerAddressRequest(PeerAddressRequest { user_name: user_name.clone(), }); context .server_request_tx .blocking_send(request) .context("sending peer address request")?; return Ok(()); } }; bail!("Unimplemented. Peer = {:?}", peer); } fn name() -> String { "PeerConnectRequestHandler".to_string() } } #[cfg(test)] mod tests { use solstice_proto::server::{PeerAddressRequest, ServerRequest}; use crate::context::ContextBundle; use crate::message_handler::MessageHandler; use crate::peer::PeerState; use super::PeerConnectRequestHandler; #[test] fn run_unknown_peer() { let mut bundle = ContextBundle::default(); PeerConnectRequestHandler::default() .run(&mut bundle.context, &"aisha".to_string()) .unwrap(); match bundle.context.state.peers.peers.get("aisha") { Some(PeerState::FetchingAddress) => (), entry => panic!("Unexpected entry: {:?}", entry), } drop(bundle.context.server_request_tx); match bundle.server_request_rx.blocking_recv() { Some(ServerRequest::PeerAddressRequest(PeerAddressRequest { user_name, })) => assert_eq!(user_name, "aisha"), Some(request) => panic!("Unexpected server request: {:?}", request), None => panic!("Expected server request, got none"), } } }