@@ -5,13 +5,13 @@ authors = ["Isabelle L. <me@izzabelle.dev>"] | |||
edition = "2018" | |||
[dependencies] | |||
structopt = "0.3.14" | |||
async-std = { version = "1.5.0",features = ["attributes"] } | |||
chrono = "0.4.11" | |||
serde = { version = "1.0.107", features = ["derive"] } | |||
serde_json = "1.0.52" | |||
uuid = { version = "0.8.1", features = ["v4"] } | |||
futures-util = "0.3.5" | |||
serde_json = "1.0.52" | |||
lazy_static = "1.4.0" | |||
structopt = "0.3.14" | |||
chrono = "0.4.11" | |||
futures = "0.3.5" | |||
futures-util = "0.3.5" | |||
toml = "0.5.6" |
@@ -1 +1 @@ | |||
username="Isabelle" | |||
user="Isabelle" |
@@ -1,3 +1,7 @@ | |||
alias rs := run-server | |||
alias rc := run-client | |||
alias b := build | |||
build: | |||
cargo build | |||
run-server: | |||
@@ -1,18 +1,25 @@ | |||
// namespacing | |||
use crate::packet::{Message, Packet}; | |||
use crate::config::ClientConfig as Config; | |||
use crate::packet::{Join, Message, Packet, Sendable}; | |||
use crate::Result; | |||
use async_std::net::TcpStream; | |||
use std::convert::TryInto; | |||
use futures_util::io::AsyncReadExt; | |||
/// wraps the client | |||
pub async fn client(port: u16) -> Result<()> { | |||
let mut stream = TcpStream::connect(format!("127.0.0.1:{}", &port)).await?; | |||
let config = Config::load()?; | |||
let stream = TcpStream::connect(format!("127.0.0.1:{}", &port)).await?; | |||
println!("connection established to: {}:{}", stream.peer_addr()?.ip(), port); | |||
let (_read, mut write) = stream.split(); | |||
let join: Packet = Join::new(config.user).to_packet()?; | |||
join.write(&mut write).await?; | |||
// testing stuffs | |||
let message: Packet = | |||
Message::new("Isabelle".to_owned(), "Hello Server".to_owned()).try_into()?; | |||
message.write(&mut stream).await?; | |||
Message::new("Isabelle".to_owned(), "Hello Server".to_owned()).to_packet()?; | |||
message.write(&mut write).await?; | |||
loop {} | |||
} |
@@ -3,7 +3,7 @@ use serde::Deserialize; | |||
#[derive(Deserialize)] | |||
pub struct ClientConfig { | |||
user: String, | |||
pub user: String, | |||
} | |||
impl ClientConfig { | |||
@@ -2,7 +2,7 @@ | |||
use crate::Result; | |||
use async_std::net::TcpStream; | |||
use async_std::prelude::*; | |||
use futures_util::io::ReadHalf; | |||
use futures_util::io::{ReadHalf, WriteHalf}; | |||
use std::convert::TryInto; | |||
mod join; | |||
@@ -29,12 +29,13 @@ impl std::convert::Into<NetworkPacket> for Packet { | |||
} | |||
} | |||
pub trait Sendable { | |||
fn to_packet(self) -> Packet; | |||
fn from_packet(packet: Packet) -> Self; | |||
pub trait Sendable: Sized { | |||
fn to_packet(self) -> Result<Packet>; | |||
fn from_packet(packet: Packet) -> Result<Self>; | |||
} | |||
/// contains data to be turned into a network packet or into a more specific packet | |||
#[derive(Debug, Clone)] | |||
pub struct Packet { | |||
pub packet_type: PacketType, | |||
packet_contents: Vec<u8>, | |||
@@ -65,7 +66,7 @@ impl Packet { | |||
} | |||
/// write a packet to the tcpstream | |||
pub async fn write(self, stream: &mut TcpStream) -> Result<()> { | |||
pub async fn write(self, stream: &mut WriteHalf<TcpStream>) -> Result<()> { | |||
let network_packet: NetworkPacket = self.into(); | |||
stream.write(&network_packet.0).await?; | |||
Ok(()) | |||
@@ -73,6 +74,7 @@ impl Packet { | |||
} | |||
/// represent the specific packet type | |||
#[derive(Debug, Clone)] | |||
#[repr(u8)] | |||
pub enum PacketType { | |||
Message = 0, | |||
@@ -84,6 +86,7 @@ impl PacketType { | |||
pub fn from_u8(packet_type: u8) -> Option<Self> { | |||
match packet_type { | |||
0 => Some(Self::Message), | |||
1 => Some(Self::Join), | |||
_ => None, | |||
} | |||
} | |||
@@ -1,5 +1,5 @@ | |||
use crate::packet::{Packet, PacketType}; | |||
use crate::{Error, Result}; | |||
use crate::Result; | |||
use chrono::prelude::*; | |||
use serde::{Deserialize, Serialize}; | |||
@@ -10,29 +10,23 @@ pub struct Join { | |||
} | |||
impl Join { | |||
fn new(user: String) -> Self { | |||
pub fn new(user: String) -> Self { | |||
let timestamp = Utc::now().timestamp(); | |||
Self { user, timestamp } | |||
} | |||
} | |||
impl std::convert::TryFrom<Packet> for Join { | |||
type Error = Error; | |||
fn try_from(packet: Packet) -> Result<Self> { | |||
let packet_contents = | |||
&String::from_utf8(packet.packet_contents).expect("could not decode as utf8"); | |||
let message: Join = serde_json::from_str(packet_contents)?; | |||
Ok(message) | |||
} | |||
} | |||
impl std::convert::TryInto<Packet> for Join { | |||
type Error = Error; | |||
fn try_into(self) -> Result<Packet> { | |||
impl crate::packet::Sendable for Join { | |||
fn to_packet(self) -> Result<Packet> { | |||
let packet_contents: Vec<u8> = serde_json::to_string(&self)?.into_bytes(); | |||
let packet_type = PacketType::Join; | |||
Ok(Packet { packet_type, packet_contents }) | |||
} | |||
fn from_packet(packet: Packet) -> Result<Self> { | |||
let packet_contents = | |||
&String::from_utf8(packet.packet_contents).expect("could not decode as utf8"); | |||
let join: Join = serde_json::from_str(packet_contents)?; | |||
Ok(join) | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
// namespacing | |||
use crate::packet::{Packet, PacketType}; | |||
use crate::{Error, Result}; | |||
use crate::Result; | |||
use chrono::prelude::*; | |||
use serde::{Deserialize, Serialize}; | |||
@@ -20,23 +20,17 @@ impl Message { | |||
} | |||
} | |||
impl std::convert::TryFrom<Packet> for Message { | |||
type Error = Error; | |||
impl crate::packet::Sendable for Message { | |||
fn to_packet(self) -> Result<Packet> { | |||
let packet_contents: Vec<u8> = serde_json::to_string(&self)?.into_bytes(); | |||
let packet_type = PacketType::Message; | |||
Ok(Packet { packet_type, packet_contents }) | |||
} | |||
fn try_from(packet: Packet) -> Result<Self> { | |||
fn from_packet(packet: Packet) -> Result<Self> { | |||
let packet_contents = | |||
&String::from_utf8(packet.packet_contents).expect("could not decode as utf8"); | |||
let message: Message = serde_json::from_str(packet_contents)?; | |||
Ok(message) | |||
} | |||
} | |||
impl std::convert::TryInto<Packet> for Message { | |||
type Error = Error; | |||
fn try_into(self) -> Result<Packet> { | |||
let packet_contents: Vec<u8> = serde_json::to_string(&self)?.into_bytes(); | |||
let packet_type = PacketType::Message; | |||
Ok(Packet { packet_type, packet_contents }) | |||
} | |||
} |
@@ -1,17 +1,17 @@ | |||
// namespacing | |||
use crate::{ | |||
packet::{Join, Message, Packet, PacketType}, | |||
packet::{Join, Message, Packet, PacketType, Sendable}, | |||
Result, | |||
}; | |||
use async_std::{ | |||
net::{TcpListener, TcpStream}, | |||
prelude::*, | |||
task, | |||
}; | |||
use futures::io::{ReadHalf, WriteHalf}; | |||
use futures_util::io::AsyncReadExt; | |||
use futures_util::stream::StreamExt; | |||
use lazy_static::lazy_static; | |||
use std::{collections::HashMap, convert::TryFrom, sync::Mutex}; | |||
use std::{collections::HashMap, sync::Mutex}; | |||
use uuid::Uuid; | |||
lazy_static! { | |||
@@ -60,11 +60,11 @@ async fn handle_stream(mut stream: ReadHalf<TcpStream>, stream_id: Uuid) -> Resu | |||
match packet.packet_type { | |||
PacketType::Message => { | |||
let msg = Message::try_from(packet)?; | |||
let msg = Message::from_packet(packet)?; | |||
println!("{:?}", msg); | |||
} | |||
PacketType::Join => { | |||
let join = Join::try_from(packet)?; | |||
let join = Join::from_packet(packet)?; | |||
println!("{:?}", join); | |||
} | |||
} | |||
@@ -78,8 +78,17 @@ async fn handle_stream(mut stream: ReadHalf<TcpStream>, stream_id: Uuid) -> Resu | |||
Ok(()) | |||
} | |||
/* | |||
async fn relay_packet() -> Result<()> { | |||
let locked_stream = WRITE_STREAMS.lock(). | |||
async fn relay_packet<T: Clone + Sendable>(packet: T) -> Result<()> { | |||
let mut locked_write_streams = WRITE_STREAMS.lock().expect("failed to aqcuire lock"); | |||
let stream = futures::stream::iter(locked_write_streams.iter_mut()); | |||
}*/ | |||
let packet = &packet; | |||
stream | |||
.for_each_concurrent(None, |(_, mut stream)| async move { | |||
let packet = packet.clone().to_packet().expect("failed to convert to packet"); | |||
// in case any of the writes fail just ignore them | |||
let _ = packet.write(&mut stream); | |||
}) | |||
.await; | |||
Ok(()) | |||
} |