use crate::protocol::*;
use log::trace;
use tokio::{
io::{AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt, BufReader},
net::TcpStream,
};
use uuid::Uuid;
pub async fn send_message<W>(writer: &mut W, msg: &MineChatMessage) -> Result<(), MineChatError>
where
W: AsyncWrite + Unpin,
{
trace!("Serializing message {:?}", msg);
let json = serde_json::to_string(msg)? + "\n";
trace!("Sending message to server");
writer.write_all(json.as_bytes()).await?;
Ok(())
}
pub async fn receive_message<R>(reader: &mut R) -> Result<MineChatMessage, MineChatError>
where
R: AsyncBufRead + Unpin,
{
let mut line = String::new();
reader.read_line(&mut line).await?;
Ok(serde_json::from_str(&line)?)
}
pub async fn link_with_server(
server_addr: impl AsRef<str>,
code: impl AsRef<str>,
) -> Result<(String, String), MineChatError> {
let addr = server_addr.as_ref();
let link_code = code.as_ref();
handle_link(addr, link_code).await
}
#[deprecated(since = "0.1.1", note = "use link_with_server instead")]
pub async fn handle_link(server_addr: &str, code: &str) -> Result<(String, String), MineChatError> {
let client_uuid = Uuid::new_v4().to_string();
trace!("Connecting to server {}", server_addr);
let mut stream = TcpStream::connect(server_addr).await?;
let (reader, mut writer) = stream.split();
trace!("Connected to server");
let mut reader = BufReader::new(reader);
trace!("Sending message to server {}", server_addr);
send_message(
&mut writer,
&MineChatMessage::Auth {
payload: AuthPayload {
client_uuid: client_uuid.clone(),
link_code: code.to_string(),
},
},
)
.await?;
match receive_message(&mut reader).await? {
MineChatMessage::AuthAck { payload } => {
if payload.status != "success" {
return Err(MineChatError::AuthFailed(payload.message));
}
trace!("Linked successfully: {}", payload.message);
Ok((client_uuid, server_addr.to_string()))
}
_ => Err(MineChatError::AuthFailed("Unexpected response".into())),
}
}