diff --git a/Cargo.lock b/Cargo.lock index a134058..52a31af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,24 +173,118 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "futures" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" +[[package]] +name = "futures-executor" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" +[[package]] +name = "futures-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" + +[[package]] +name = "futures-task" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" +dependencies = [ + "once_cell", +] + [[package]] name = "futures-timer" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" +[[package]] +name = "futures-util" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "heck" version = "0.3.1" @@ -333,9 +427,13 @@ version = "0.1.0" dependencies = [ "async-std", "chrono", + "futures", + "futures-util", + "lazy_static", "serde", "serde_json", "structopt", + "uuid", ] [[package]] @@ -384,6 +482,26 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +[[package]] +name = "pin-project" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50dab4a05419117fe00216df4731e387ae616cd2a5f5dda1d8b02d863ac63d" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c27e5ac1d4c76777afd4d47b8fe9c602b44bcf6f999d34e300bba5560c9837b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.1.5" @@ -396,6 +514,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" + [[package]] name = "proc-macro-error" version = "1.0.2" @@ -422,6 +546,18 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" + +[[package]] +name = "proc-macro-nested" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" + [[package]] name = "proc-macro2" version = "1.0.12" @@ -440,6 +576,47 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + [[package]] name = "ryu" version = "1.0.4" @@ -578,6 +755,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +[[package]] +name = "uuid" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" +dependencies = [ + "rand", +] + [[package]] name = "vec_map" version = "0.8.2" @@ -590,6 +776,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index ba0b468..87912f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,7 @@ 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"] } +lazy_static = "1.4.0" +futures = "0.3.5" +futures-util = "0.3.5" diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..17e49de --- /dev/null +++ b/src/client.rs @@ -0,0 +1,18 @@ +// namespacing +use crate::packet::{Message, Packet}; +use crate::Result; +use async_std::net::TcpStream; +use std::convert::TryInto; + +/// wraps the client +pub async fn client(port: u16) -> Result<()> { + let mut stream = TcpStream::connect(format!("127.0.0.1:{}", &port)).await?; + println!("connection established to: {}:{}", stream.peer_addr()?.ip(), port); + + // testing stuffs + let message: Packet = + Message::new("Isabelle".to_owned(), "Hello Server".to_owned()).try_into()?; + message.write(&mut stream).await?; + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index 669a9cf..8fc3ddc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,54 +1,13 @@ -use async_std::net::TcpListener; -use async_std::net::TcpStream; -use async_std::prelude::*; -use std::convert::{TryFrom, TryInto}; - -use packet::{Message, Packet, PacketType}; - +// modules +mod client; +#[allow(dead_code)] mod packet; +mod server; -pub type Result = std::result::Result>; - -pub async fn server(port: u16) -> Result<()> { - let listener = TcpListener::bind(format!("127.0.0.1:{}", &port)).await?; - println!( - "online as server at: {}:{}", - listener.local_addr()?.ip(), - port - ); - let mut incoming = listener.incoming(); - - while let Some(stream) = incoming.next().await { - let mut stream = stream?; - println!("new stream from: {}", stream.peer_addr()?.ip()); - // handle stream - - // testing - let packet = Packet::read(&mut stream).await?; - let message = match packet.packet_type { - PacketType::Message => Message::try_from(packet), - }; - println!("{:?}", message); - } - - Ok(()) -} - -pub async fn client(port: u16) -> Result<()> { - let mut stream = TcpStream::connect(format!("127.0.0.1:{}", &port)).await?; - println!( - "connection established to: {}:{}", - stream.peer_addr()?.ip(), - port - ); - - // testing stuffs - let message: Packet = - Message::new("Isabelle".to_owned(), "Hello Server".to_owned()).try_into()?; - message.write(&mut stream).await?; +// re-exports +pub use client::client; +pub use server::server; - /*let mut buf = vec![0u8; 1024]; - stream.read(&mut buf).await?; - println!("{}", String::from_utf8_lossy(&mut buf));*/ - Ok(()) -} +// lazy idiot error/result type +pub type Error = Box; +pub type Result = std::result::Result; diff --git a/src/main.rs b/src/main.rs index 5f08256..8ec83ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ +// namespacing use structopt::StructOpt; +// cli options #[derive(StructOpt)] #[structopt(name = "msg", about = "I have no idea what i'm doing but this is async")] struct Opt { diff --git a/src/packet.rs b/src/packet.rs index 0524dc8..1faf4e2 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -1,5 +1,5 @@ // namespacing -use crate::Result; +use crate::{Error, Result}; use async_std::net::TcpStream; use async_std::prelude::*; use chrono::prelude::*; @@ -20,23 +20,24 @@ impl std::convert::Into for Packet { contents.extend_from_slice(&contents_length.to_le_bytes()); // write the rest of the contents contents.extend_from_slice(&self.packet_contents); + NetworkPacket(contents) } } +/// contains data to be turned into a network packet or into a more specific packet pub struct Packet { pub packet_type: PacketType, packet_contents: Vec, } impl Packet { + /// create a new packet pub fn new(packet_type: PacketType, packet_contents: Vec) -> Self { - Self { - packet_type, - packet_contents, - } + Self { packet_type, packet_contents } } + /// read a packet from a tcpstream pub async fn read(stream: &mut TcpStream) -> Result { let mut info_buf = [0u8; 5]; stream.read(&mut info_buf).await?; @@ -50,6 +51,7 @@ impl Packet { Ok(Packet::new(packet_type, contents)) } + /// write a packet to the tcpstream pub async fn write(self, stream: &mut TcpStream) -> Result<()> { let network_packet: NetworkPacket = self.into(); let _ = stream.write(&network_packet.0).await?; @@ -57,12 +59,14 @@ impl Packet { } } +/// represent the specific packet type #[repr(u8)] pub enum PacketType { Message = 0, } impl PacketType { + /// returns the PacketType if the u8 is a valid packet type pub fn from_u8(packet_type: u8) -> Option { match packet_type { 0 => Some(Self::Message), @@ -71,6 +75,7 @@ impl PacketType { } } +/// a Message #[derive(Deserialize, Serialize, Debug)] pub struct Message { user: String, @@ -79,20 +84,17 @@ pub struct Message { } impl Message { + /// create a new message pub fn new(user: String, contents: String) -> Self { let timestamp = Utc::now().timestamp(); - Self { - user, - contents, - timestamp, - } + Self { user, contents, timestamp } } } impl std::convert::TryFrom for Message { - type Error = Box; + type Error = Error; - fn try_from(packet: Packet) -> crate::Result { + fn try_from(packet: Packet) -> Result { let packet_contents = &String::from_utf8(packet.packet_contents)?; let message: Message = serde_json::from_str(packet_contents)?; Ok(message) @@ -100,14 +102,11 @@ impl std::convert::TryFrom for Message { } impl std::convert::TryInto for Message { - type Error = Box; + type Error = Error; - fn try_into(self) -> crate::Result { + fn try_into(self) -> Result { let packet_contents: Vec = serde_json::to_string(&self)?.into_bytes(); let packet_type = PacketType::Message; - Ok(Packet { - packet_type, - packet_contents, - }) + Ok(Packet { packet_type, packet_contents }) } } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..6dce178 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,46 @@ +// namespacing +/*use crate::packet::{Message, Packet, PacketType};*/ +use crate::Result; +use async_std::net::{TcpListener, TcpStream}; +use async_std::prelude::*; +/*use async_std::task;*/ +use futures::io::WriteHalf; +use lazy_static::lazy_static; +use std::collections::HashMap; +/*use std::convert::TryFrom;*/ +use futures_util::io::AsyncReadExt; +use std::sync::Mutex; +use uuid::Uuid; + +lazy_static! { + static ref WRITE_STREAMS: Mutex>> = + Mutex::new(HashMap::new()); +} + +/// wraps the server +pub async fn server(port: u16) -> Result<()> { + let listener = TcpListener::bind(format!("127.0.0.1:{}", &port)).await?; + println!("online as server at: {}:{}", listener.local_addr()?.ip(), port); + let mut incoming = listener.incoming(); + + while let Some(stream) = incoming.next().await { + let mut stream = stream?; + println!("new stream from: {}", &stream.peer_addr()?.ip()); + let (read, write) = stream.split(); + let stream_id = Uuid::new_v4(); + WRITE_STREAMS.lock()?.insert(stream_id, write); + + // handle stream + /* task::spawn(async { + loop { + let packet = Packet::read(&mut stream).await?; + let message = match packet.packet_type { + PacketType::Message => Message::try_from(packet), + }; + println!("{:?}", message); + } + });*/ + } + + Ok(()) +}