running rust formatter

This commit is contained in:
michael-bailey 2021-03-23 10:59:36 +00:00
parent c9bb9d7567
commit e377ace2ae
14 changed files with 303 additions and 276 deletions

View File

@ -1,3 +1,3 @@
fn main() {
println!("Hello, world!");
println!("Hello, world!");
}

View File

@ -1,2 +1,2 @@
pub mod messages;
pub mod prelude;
pub mod messages;

View File

@ -1,27 +1,26 @@
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
/// # ClientMessage
/// This enum defined the message that a client can receive from the server
/// This uses the serde library to transform to and from json.
///
/// This uses the serde library to transform to and from json.
///
#[derive(Serialize, Deserialize)]
pub enum ClientStreamIn {
Connected,
Connected,
Update,
SendMessage {to_uuid: String, contents: String},
SendGlobalMessage {contents: String},
Update,
SendMessage { to_uuid: String, contents: String },
SendGlobalMessage { contents: String },
Disconnect,
Disconnect,
}
#[derive(Serialize, Deserialize)]
pub enum ClientStreamOut {
Connected,
Connected,
UserMessage {from_uuid: String, contents: String},
GlobalMessage {contents: String},
UserMessage { from_uuid: String, contents: String },
GlobalMessage { contents: String },
Disconnected,
}
Disconnected,
}

View File

@ -1,2 +1,2 @@
pub mod client;
pub mod network;
pub mod network;

View File

@ -1,16 +1,22 @@
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub enum NetworkSockIn {
Info,
Connect {uuid: String, username: String, address: String},
Info,
Connect {
uuid: String,
username: String,
address: String,
},
}
#[derive(Serialize, Deserialize)]
pub enum NetworkSockOut<'a> {
Request,
GotInfo {server_name: &'a str, server_owner: &'a str},
Connecting,
}
GotInfo {
server_name: &'a str,
server_owner: &'a str,
},
Connecting,
}

View File

@ -2,7 +2,7 @@ use std::sync::Arc;
pub trait IMessagable<TMessage, TSender> {
fn send_message(&self, msg: TMessage);
fn set_sender(&self, sender: TSender);
fn set_sender(&self, sender: TSender);
}
pub trait ICooperative {
@ -12,4 +12,4 @@ pub trait ICooperative {
pub trait IPreemtive {
fn run(arc: &Arc<Self>) {}
fn start(arc: &Arc<Self>);
}
}

2
rustfmt.toml Normal file
View File

@ -0,0 +1,2 @@
hard_tabs = true
max_width = 80

View File

@ -1,152 +1,159 @@
use std::mem::replace;
use crate::messages::ClientMessage;
use crate::messages::ServerMessage;
use std::cmp::Ordering;
use std::net::TcpStream;
use std::sync::Mutex;
use std::sync::Arc;
use std::io::{BufReader, BufWriter};
use std::io::BufRead;
use std::io::{BufReader, BufWriter};
use std::mem::replace;
use std::net::TcpStream;
use std::sync::Arc;
use std::sync::Mutex;
use crossbeam_channel::{unbounded, Receiver, Sender};
use serde::Serialize;
use uuid::Uuid;
use serde::{Serialize};
use crossbeam_channel::{Sender, Receiver, unbounded};
use foundation::messages::client::ClientStreamIn;
use foundation::prelude::{ICooperative, IMessagable};
use foundation::messages::client::{ClientStreamIn};
/// # Client
/// This struct represents a connected user.
///
///
/// ## Attrubutes
/// - uuid: The id of the connected user.
/// - username: The username of the connected user.
/// - address: The the address of the connected client.
///
///
/// - stream: The socket for the connected client.
/// - owner: An optional reference to the owning object.
#[derive(Debug, Serialize)]
pub struct Client {
pub uuid: Uuid,
username: String,
address: String,
pub uuid: Uuid,
username: String,
address: String,
// non serializable
#[serde(skip)]
server_channel: Mutex<Option<Sender<ServerMessage>>>,
#[serde(skip)]
input: Sender<ClientMessage>,
#[serde(skip)]
output: Receiver<ClientMessage>,
server_channel: Mutex<Option<Sender<ServerMessage>>>,
#[serde(skip)]
stream: Mutex<Option<TcpStream>>,
input: Sender<ClientMessage>,
#[serde(skip)]
stream_reader: Mutex<Option<BufReader<TcpStream>>>,
#[serde(skip)]
output: Receiver<ClientMessage>,
#[serde(skip)]
stream_writer: Mutex<Option<BufWriter<TcpStream>>>,
#[serde(skip)]
stream: Mutex<Option<TcpStream>>,
#[serde(skip)]
stream_reader: Mutex<Option<BufReader<TcpStream>>>,
#[serde(skip)]
stream_writer: Mutex<Option<BufWriter<TcpStream>>>,
}
// client funciton implmentations
impl Client {
pub fn new(
pub fn new(
uuid: String,
username: String,
address: String,
stream: TcpStream,
server_channel: Sender<ServerMessage>
server_channel: Sender<ServerMessage>,
) -> Arc<Client> {
let (sender, receiver) = unbounded();
let (sender, receiver) = unbounded();
let out_stream = stream.try_clone().unwrap();
let in_stream = stream.try_clone().unwrap();
let out_stream = stream.try_clone().unwrap();
let in_stream = stream.try_clone().unwrap();
Arc::new(Client {
username,
uuid: Uuid::parse_str(&uuid).expect("invalid id"),
address,
Arc::new(Client {
username,
uuid: Uuid::parse_str(&uuid).expect("invalid id"),
address,
server_channel: Mutex::new(Some(server_channel)),
server_channel: Mutex::new(Some(server_channel)),
input: sender,
output: receiver,
input: sender,
output: receiver,
stream: Mutex::new(Some(stream)),
stream: Mutex::new(Some(stream)),
stream_reader: Mutex::new(Some(BufReader::new(in_stream))),
stream_writer: Mutex::new(Some(BufWriter::new(out_stream))),
})
}
stream_reader: Mutex::new(Some(BufReader::new(in_stream))),
stream_writer: Mutex::new(Some(BufWriter::new(out_stream))),
})
}
// MARK: - removeable
pub fn send(&self, _bytes: Vec<u8>) -> Result<(), &str> { todo!() }
pub fn recv(&self) -> Option<Vec<u8>> { todo!() }
pub fn send(&self, _bytes: Vec<u8>) -> Result<(), &str> {
todo!()
}
pub fn recv(&self) -> Option<Vec<u8>> {
todo!()
}
// Mark: end -
}
impl IMessagable<ClientMessage, Sender<ServerMessage>> for Client{
impl IMessagable<ClientMessage, Sender<ServerMessage>> for Client {
fn send_message(&self, msg: ClientMessage) {
self.input.send(msg).expect("failed to send message to client.");
self.input
.send(msg)
.expect("failed to send message to client.");
}
fn set_sender(&self, sender: Sender<ServerMessage>) {
let mut server_lock = self.server_channel.lock().unwrap();
let _ = replace(&mut *server_lock, Some(sender));
}
fn set_sender(&self, sender: Sender<ServerMessage>) {
let mut server_lock = self.server_channel.lock().unwrap();
let _ = replace(&mut *server_lock, Some(sender));
}
}
// cooperative multitasking implementation
impl ICooperative for Client {
fn tick(&self) {
println!("[client]: Tick!");
{
// aquire locks (so value isn't dropped)
let mut reader_lock = self.stream_reader.lock().unwrap();
let mut writer_lock = self.stream_writer.lock().unwrap();
println!("[client]: Tick!");
{
// aquire locks (so value isn't dropped)
let mut reader_lock = self.stream_reader.lock().unwrap();
let mut writer_lock = self.stream_writer.lock().unwrap();
// aquiring mutable buffers
let reader = reader_lock.as_mut().unwrap();
let _writer = writer_lock.as_mut().unwrap();
// aquiring mutable buffers
let reader = reader_lock.as_mut().unwrap();
let _writer = writer_lock.as_mut().unwrap();
// create buffer
let mut buffer = String::new();
// create buffer
let mut buffer = String::new();
// loop over all lines that have been sent.
while let Ok(_size) = reader.read_line(&mut buffer) {
let command = serde_json::from_str::<ClientStreamIn>(buffer.as_str()).unwrap();
// loop over all lines that have been sent.
while let Ok(_size) = reader.read_line(&mut buffer) {
let command =
serde_json::from_str::<ClientStreamIn>(buffer.as_str())
.unwrap();
match command {
ClientStreamIn::Disconnect => println!("got Disconnect"),
_ => println!("New command found"),
}
}
}
match command {
ClientStreamIn::Disconnect => println!("got Disconnect"),
_ => println!("New command found"),
}
}
}
{
for message in self.output.iter() {
use ClientMessage::{Disconnect};
match message {
Disconnect => {
let lock = self.server_channel.lock().unwrap();
if let Some(sender) = lock.as_ref() {
sender.send(ServerMessage::ClientDisconnected(self.uuid)).unwrap();
}
},
_ => println!("command not implemneted yet"),
}
}
}
{
for message in self.output.iter() {
use ClientMessage::Disconnect;
match message {
Disconnect => {
let lock = self.server_channel.lock().unwrap();
if let Some(sender) = lock.as_ref() {
sender
.send(ServerMessage::ClientDisconnected(
self.uuid,
))
.unwrap();
}
}
_ => println!("command not implemneted yet"),
}
}
}
// handle incomming messages
// handle incomming messages
}
}
@ -156,40 +163,39 @@ impl Default for Client {
let (sender, reciever) = unbounded();
Client {
username: "generic_client".to_string(),
uuid: Uuid::new_v4(),
address: "127.0.0.1".to_string(),
uuid: Uuid::new_v4(),
address: "127.0.0.1".to_string(),
output: reciever,
output: reciever,
input: sender,
server_channel: Mutex::new(None),
server_channel: Mutex::new(None),
stream: Mutex::new(None),
stream: Mutex::new(None),
stream_reader: Mutex::new(None),
stream_writer: Mutex::new(None),
stream_reader: Mutex::new(None),
stream_writer: Mutex::new(None),
}
}
}
// MARK: - used for sorting.
impl PartialEq for Client {
fn eq(&self, other: &Self) -> bool {
self.uuid == other.uuid
}
fn eq(&self, other: &Self) -> bool {
self.uuid == other.uuid
}
}
impl Eq for Client {
}
impl Eq for Client {}
impl PartialOrd for Client {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
Some(self.cmp(other))
}
}
impl Ord for Client {
fn cmp(&self, other: &Self) -> Ordering {
self.uuid.cmp(&other.uuid)
}
fn cmp(&self, other: &Self) -> Ordering {
self.uuid.cmp(&other.uuid)
}
}

View File

@ -1,60 +1,57 @@
// use crate::lib::server::ServerMessages;
use foundation::prelude::IPreemtive;
use std::sync::Arc;
use std::sync::Mutex;
use std::collections::HashMap;
use std::mem::replace;
use std::sync::Arc;
use std::sync::Mutex;
use crossbeam_channel::{unbounded, Receiver, Sender};
use uuid::Uuid;
use crate::client::Client;
use crate::messages::ClientMessage;
use crate::messages::ClientMgrMessage;
use crate::messages::ServerMessage;
use crate::messages::ClientMessage;
use foundation::prelude::IMessagable;
use foundation::prelude::ICooperative;
/// # ClientManager
/// This struct manages all connected users
#[derive(Debug)]
pub struct ClientManager {
clients: Mutex<HashMap<Uuid, Arc<Client>>>,
clients: Mutex<HashMap<Uuid, Arc<Client>>>,
server_channel: Mutex<Sender<ServerMessage>>,
sender: Sender<ClientMgrMessage>,
receiver: Receiver<ClientMgrMessage>,
sender: Sender<ClientMgrMessage>,
receiver: Receiver<ClientMgrMessage>,
}
impl ClientManager {
pub fn new(server_channel: Sender<ServerMessage>) -> Arc<Self> {
pub fn new(server_channel: Sender<ServerMessage>) -> Arc<Self> {
let (sender, receiver) = unbounded();
let (sender, receiver) = unbounded();
Arc::new(ClientManager {
clients: Mutex::default(),
Arc::new(ClientManager {
clients: Mutex::default(),
server_channel: Mutex::new(server_channel),
sender,
receiver,
})
}
sender,
receiver,
})
}
}
impl IMessagable<ClientMgrMessage, Sender<ServerMessage>> for ClientManager {
fn send_message(&self, msg: ClientMgrMessage) {
self.sender.send(msg).unwrap();
}
fn set_sender(&self, sender: Sender<ServerMessage>) {
let mut server_lock = self.server_channel.lock().unwrap();
let _ = replace(&mut *server_lock, sender);
}
self.sender.send(msg).unwrap();
}
fn set_sender(&self, sender: Sender<ServerMessage>) {
let mut server_lock = self.server_channel.lock().unwrap();
let _ = replace(&mut *server_lock, sender);
}
}
impl IPreemtive for ClientManager {
fn run(arc: &Arc<Self>) {
loop {
std::thread::sleep(std::time::Duration::from_secs(1));
@ -67,29 +64,33 @@ impl IPreemtive for ClientManager {
match message {
Add(client) => {
arc.clients.lock().unwrap().insert(client.uuid, client).unwrap_or_default();
},
arc.clients
.lock()
.unwrap()
.insert(client.uuid, client)
.unwrap_or_default();
}
Remove(uuid) => {
let _ = arc.clients.lock().unwrap().remove(&uuid);
},
}
SendMessage(to_uuid, from_uuid, content) => {
let lock = arc.clients.lock().unwrap();
if let Some(client) = lock.get(&to_uuid) {
client.send_message(ClientMessage::Message(from_uuid, content))
client.send_message(ClientMessage::Message(
from_uuid, content,
))
}
},
}
#[allow(unreachable_patterns)]
_ => println!("[Client manager]: not implemented")
_ => println!("[Client manager]: not implemented"),
}
}
}
}
}
fn start(arc: &Arc<Self>) {
fn start(arc: &Arc<Self>) {
let arc = arc.clone();
std::thread::spawn(move || {
ClientManager::run(&arc)
});
}
}
std::thread::spawn(move || ClientManager::run(&arc));
}
}

View File

@ -1,16 +1,16 @@
pub mod server;
pub mod network_manager;
pub mod client;
pub mod client_manager;
pub mod messages;
pub mod network_manager;
pub mod server;
use clap::{App, Arg};
use foundation::prelude::IPreemtive;
use server::Server;
fn main() {
let _args = App::new("--rust chat server--")
let _args = App::new("--rust chat server--")
.version("0.1.5")
.author("Mitchel Hardie <mitch161>, Michael Bailey <michael-bailey>")
.about("this is a chat server developed in rust, depending on the version one of two implementations will be used")

View File

@ -1,24 +1,24 @@
use uuid::Uuid;
use std::sync::Arc;
use uuid::Uuid;
use crate::client::Client;
#[derive(Debug)]
pub enum ClientMessage {
Message(Uuid, String),
Message(Uuid, String),
Disconnect,
Disconnect,
}
#[derive(Debug)]
pub enum ClientMgrMessage {
Remove(Uuid),
Add(Arc<Client>),
SendMessage(Uuid, Uuid, String),
Remove(Uuid),
Add(Arc<Client>),
SendMessage(Uuid, Uuid, String),
}
#[derive(Debug)]
pub enum ServerMessage {
ClientConnected(Arc<Client>),
ClientDisconnected(Uuid)
}
ClientConnected(Arc<Client>),
ClientDisconnected(Uuid),
}

View File

@ -1,44 +1,43 @@
use foundation::prelude::IPreemtive;
use std::io::BufWriter;
use std::io::BufReader;
use std::io::Write;
use std::io::BufRead;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Write;
use std::net::TcpListener;
use std::sync::Arc;
use std::thread;
use crossbeam_channel::{Sender};
use crossbeam_channel::Sender;
use foundation::prelude::ICooperative;
use foundation::messages::network::{NetworkSockIn, NetworkSockOut};
use crate::client::Client;
use crate::messages::ServerMessage;
use foundation::messages::network::{NetworkSockIn, NetworkSockOut};
pub struct NetworkManager {
listener: TcpListener,
server_channel: Sender<ServerMessage>,
listener: TcpListener,
server_channel: Sender<ServerMessage>,
}
impl NetworkManager {
pub fn new(
port: String,
server_channel: Sender<ServerMessage>
pub fn new(
port: String,
server_channel: Sender<ServerMessage>,
) -> Arc<NetworkManager> {
let mut address = "0.0.0.0:".to_string();
address.push_str(&port);
let mut address = "0.0.0.0:".to_string();
address.push_str(&port);
let listener = TcpListener::bind(address)
.expect("Could not bind to address");
let listener =
TcpListener::bind(address).expect("Could not bind to address");
Arc::new(NetworkManager {
listener,
server_channel,
})
}
Arc::new(NetworkManager {
listener,
server_channel,
})
}
}
impl IPreemtive for NetworkManager {
fn start(arc: &Arc<Self>) {
fn start(arc: &Arc<Self>) {
let arc = arc.clone();
std::thread::spawn(move || {
// fetch new connections and add them to the client queue
@ -49,31 +48,44 @@ impl IPreemtive for NetworkManager {
let server_channel = arc.server_channel.clone();
// create readers
let mut reader = BufReader::new(stream.try_clone().unwrap());
let mut writer = BufWriter::new(stream.try_clone().unwrap());
let mut reader =
BufReader::new(stream.try_clone().unwrap());
let mut writer =
BufWriter::new(stream.try_clone().unwrap());
let _handle = thread::Builder::new()
.name("NetworkJoinThread".to_string())
.spawn(move || {
let mut buffer = String::new();
let mut buffer = String::new();
// send request message to connection
writer.write_all(
serde_json::to_string(&NetworkSockOut::Request).unwrap().as_bytes()
).unwrap_or_default();
writer.write_all(b"\n").unwrap_or_default();
writer.flush().unwrap_or_default();
// send request message to connection
writer
.write_all(
serde_json::to_string(
&NetworkSockOut::Request,
)
.unwrap()
.as_bytes(),
)
.unwrap_or_default();
writer.write_all(b"\n").unwrap_or_default();
writer.flush().unwrap_or_default();
// try get response
let res = reader.read_line(&mut buffer);
if res.is_err() {return;}
// try get response
let res = reader.read_line(&mut buffer);
if res.is_err() {
return;
}
//match the response
if let Ok(request) = serde_json::from_str::<NetworkSockIn>(&buffer) {
match request {
NetworkSockIn::Info => {
// send back server info to the connection
writer.write_all(
//match the response
if let Ok(request) = serde_json::from_str::<
NetworkSockIn,
>(&buffer)
{
match request {
NetworkSockIn::Info => {
// send back server info to the connection
writer.write_all(
serde_json::to_string(
&NetworkSockOut::GotInfo {
server_name: "oof",
@ -81,32 +93,39 @@ impl IPreemtive for NetworkManager {
}
).unwrap().as_bytes()
).unwrap();
writer.write_all(b"\n").unwrap();
writer.flush().unwrap();
}
NetworkSockIn::Connect { uuid, username, address } => {
// create client and send to server
let new_client = Client::new(
writer.write_all(b"\n").unwrap();
writer.flush().unwrap();
}
NetworkSockIn::Connect {
uuid,
username,
address,
stream.try_clone().unwrap(),
server_channel.clone()
);
server_channel.send(
} => {
// create client and send to server
let new_client = Client::new(
uuid,
username,
address,
stream.try_clone().unwrap(),
server_channel.clone(),
);
server_channel.send(
ServerMessage::ClientConnected(new_client)
).unwrap_or_default();
}
}
}
}
});
},
});
}
Err(e) => {
println!("[Network manager]: error getting stream: {:?}", e);
println!(
"[Network manager]: error getting stream: {:?}",
e
);
continue;
},
}
}
}
});
}
}
}
}

View File

@ -1,30 +1,30 @@
use std::sync::Arc;
use std::thread;
use crossbeam_channel::{unbounded, Receiver};
use uuid::Uuid;
use crossbeam_channel::{Receiver, unbounded};
use foundation::prelude::IPreemtive;
use foundation::prelude::ICooperative;
use foundation::prelude::IMessagable;
use crate::client_manager::ClientManager;
use crate::network_manager::NetworkManager;
use crate::messages::ClientMgrMessage;
use crate::messages::ServerMessage;
use crate::network_manager::NetworkManager;
use foundation::prelude::ICooperative;
use foundation::prelude::IMessagable;
use foundation::prelude::IPreemtive;
/// # ServerMessages
/// This is used internally
/// This is used internally
#[derive(Debug)]
pub enum ServerMessages<TClient> {
ClientConnected(Arc<TClient>),
#[allow(dead_code)]
ClientDisconnected(Uuid),
#[allow(dead_code)]
ClientDisconnected(Uuid),
}
pub struct Server {
client_manager: Arc<ClientManager>,
network_manager: Arc<NetworkManager>,
network_manager: Arc<NetworkManager>,
receiver: Receiver<ServerMessage>,
}
@ -36,46 +36,42 @@ impl Server {
Arc::new(Server {
client_manager: ClientManager::new(sender.clone()),
network_manager: NetworkManager::new("5600".to_string(), sender),
network_manager: NetworkManager::new("5600".to_string(), sender),
receiver,
})
}
}
impl ICooperative for Server{
impl ICooperative for Server {
fn tick(&self) {
println!("[server]: Tick!");
use ClientMgrMessage::{Remove, Add};
println!("[server]: Tick!");
use ClientMgrMessage::{Add, Remove};
// handle new messages loop
if !self.receiver.is_empty() {
println!("[server]: entering loop!");
for message in self.receiver.try_iter() {
println!("[server]: received message {:?}", &message);
match message {
ServerMessage::ClientConnected(client) => {
self.client_manager.send_message(Add(client))
},
ServerMessage::ClientDisconnected(uuid) => {
println!("disconnecting client {:?}", uuid);
self.client_manager.send_message(Remove(uuid));
}
}
}
}
if !self.receiver.is_empty() {
println!("[server]: entering loop!");
for message in self.receiver.try_iter() {
println!("[server]: received message {:?}", &message);
match message {
ServerMessage::ClientConnected(client) => {
self.client_manager.send_message(Add(client))
}
ServerMessage::ClientDisconnected(uuid) => {
println!("disconnecting client {:?}", uuid);
self.client_manager.send_message(Remove(uuid));
}
}
}
}
// alocate time for other components
println!("[server]: allocating time for others");
//
println!("[server]: allocating time for others");
//
}
}
impl IPreemtive for Server {
fn run(arc: &std::sync::Arc<Self>) {
// start services
NetworkManager::start(&arc.network_manager);
@ -85,12 +81,10 @@ impl IPreemtive for Server {
arc.tick();
}
}
fn start(arc: &std::sync::Arc<Self>) {
let arc = arc.clone();
// start thread
std::thread::spawn(move || {
Server::run(&arc)
});
std::thread::spawn(move || Server::run(&arc));
}
}
}

View File

@ -1,3 +1,3 @@
fn main() {
println!("Hello, world!");
println!("Hello, world!");
}