You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.0 KiB
85 lines
2.0 KiB
5 years ago
|
use std::fmt;
|
||
|
use std::io::{BufRead, BufReader, BufWriter, ErrorKind, Write};
|
||
|
use std::net::SocketAddr;
|
||
|
|
||
|
use log::error;
|
||
|
|
||
|
use mio::net::TcpStream;
|
||
|
use mio::Token;
|
||
|
|
||
|
use crate::result::RudeResult;
|
||
|
use crate::state::*;
|
||
|
|
||
|
/// `Client` struct for storing information about a connected client, also
|
||
|
/// a few helper functions for communicating with the client.
|
||
|
#[derive(Debug)]
|
||
|
pub struct Client {
|
||
|
/// TCP socket
|
||
|
pub socket: TcpStream,
|
||
|
|
||
|
/// Identifier token
|
||
|
pub token: Token,
|
||
|
|
||
|
/// IP information
|
||
|
pub addr: SocketAddr,
|
||
|
|
||
|
/// Client's play state
|
||
|
pub state: State,
|
||
|
}
|
||
|
|
||
|
impl fmt::Display for Client {
|
||
|
/// Only need the ip and port to be printed.
|
||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||
|
write!(f, "{}:{}", self.addr.ip(), self.addr.port())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Into<String> for Client {
|
||
|
/// Convert the ip and port into a string.
|
||
|
fn into(self) -> String {
|
||
|
format!("{}:{}", self.addr.ip(), self.addr.port())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Client {
|
||
|
/// Read a message from the client
|
||
|
pub fn read(&self) -> RudeResult<String> {
|
||
|
let reader = BufReader::new(&self.socket);
|
||
|
let mut buf = String::new();
|
||
|
|
||
|
for line in reader.lines() {
|
||
|
match line {
|
||
|
Ok(line) => buf += &line,
|
||
|
Err(e) => match e.kind() {
|
||
|
ErrorKind::WouldBlock => break,
|
||
|
_ => return Err(e.into()),
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Ok(buf)
|
||
|
}
|
||
|
|
||
|
/// Send a string to the client.
|
||
|
pub fn send_without_prompt<T: Into<String>>(&mut self, message: T) {
|
||
|
let message = message.into();
|
||
|
let mut writer = BufWriter::new(&self.socket);
|
||
|
if let Err(e) = writer.write_all(message.as_bytes()) {
|
||
|
error!("Unable to send message to client ({:?}): {}", self, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Send a string to the client, followed by a prompt.
|
||
|
pub fn send_with_prompt<T: Into<String>>(&mut self, message: T) {
|
||
|
let message = message.into() + self.prompt();
|
||
|
let mut writer = BufWriter::new(&self.socket);
|
||
|
if let Err(e) = writer.write_all(message.as_bytes()) {
|
||
|
error!("Unable to send message to client ({:?}): {}", self, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn prompt(&self) -> &str {
|
||
|
"\n> "
|
||
|
}
|
||
|
}
|