diff --git a/Cargo.lock b/Cargo.lock index d19f508..73b1a7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,6 +60,11 @@ dependencies = [ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "either" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -79,6 +84,98 @@ name = "futures" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "futures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-async-runtime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-stable 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-async-runtime" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-stable 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-channel" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-executor" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-channel 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-sink" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-stable" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "futures-util" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "iovec" version = "0.1.2" @@ -181,6 +278,7 @@ dependencies = [ name = "plankircd" version = "0.1.0" dependencies = [ + "futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -368,9 +466,19 @@ dependencies = [ "checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7" "checksum crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2af0e75710d6181e234c8ecc79f14a97907850a541b13b0be1dd10992f2e4620" "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" +"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" +"checksum futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d81ccac876e9e5efad47774552d1ecc05828886ad64468bc716595659bd078cb" +"checksum futures-async-runtime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bab8d196f9bcbc3b33148960602889bf44c74afe5bea20ee970aaa08df2db2f5" +"checksum futures-channel 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bbb37ec6418c577b25f5b129c0f4456ad7ce8714ec43c59712aa7e4cd2cb6b85" +"checksum futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7455c91eb2eae38f33b013f77ebe766c75761af333efd9d550e154045c63e225" +"checksum futures-executor 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5db1dd3979745f5e50b28fd604602f2715f9d5a28ab835a5f9686a9d84cd1315" +"checksum futures-io 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6a0470fdba9dc87c27a3564ad6d5cc04e080f3afa26c93549728cce46ab21a2" +"checksum futures-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8a93a7c480876b8e02cdd70022e7eb9c8423575ea6a25a0b749b18834c16412" +"checksum futures-stable 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a222f540db94a09c275be08a406b5cd82f4311422b940a684795cdaef3d02e81" +"checksum futures-util 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cf12a3fc1ccaf1bc2901ec6e0ed6ed407a4f16eaa20dd838f40cabf5f7b31f1" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" diff --git a/Cargo.toml b/Cargo.toml index c4f161f..744b12c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" authors = ["Adrian Hedqvist "] [dependencies] -tokio = "0.1" \ No newline at end of file +tokio = "0.1" +futures = "0.2" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9f55f52..6a08c70 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,36 +1,75 @@ extern crate tokio; +extern crate futures; use tokio::prelude::*; -use tokio::io::copy; +use tokio::io; +use std::iter; +use std::collections::HashMap; +use std::io::BufReader; use tokio::net::TcpListener; +use std::sync::{Arc, Mutex}; pub mod models; - +pub mod user; +/* +struct Context { + connections: Arc>>, + users: Arc>>, + channels: Arc>>, +} +*/ fn main() { let addr = "127.0.0.1:6667".parse().unwrap(); let listener = TcpListener::bind(&addr) .expect("unable to bind TCP listener"); + let mut connections = Arc::new(Mutex::new(HashMap::new())); + //let mut users = Arc::new(Mutex::new(HashMap::new())); + //let mut channels = Arc::new(Mutex::new(HashMap::new())); + let server = listener.incoming() .map_err(|e| eprintln!("accept failed = {:?}", e)) .for_each(|sock| { - // Split up the reading and writing parts of the - // socket. + let addr = sock.peer_addr().unwrap(); + println!("{} connected", addr); let (reader, writer) = sock.split(); + let (tx, rx) = futures::channel::mpsc::unbounded(); - // A future that echos the data and returns how - // many bytes were copied... - let bytes_copied = copy(reader, writer); + connections.lock().unwrap().insert(addr, tx); - // ... after which we'll print what happened. - let handle_conn = bytes_copied.map(|amt| { - println!("wrote {:?} bytes", amt) - }).map_err(|err| { - eprintln!("IO error {:?}", err) + let bufreader = BufReader::new(reader); + + let iter = stream::iter_ok::<_, io::Error>(iter::repeat(())); + let socket_reader = iter.fold(bufreader, move |reader, _| { + io::read_until(reader, b'\n', vec![]) + .and_then(|(reader, vec)| { + if vec.len() == 0 { + Err(io::Error::new(io::ErrorKind::BrokenPipe, "broken pipe")) + } + else { + Ok((reader, vec)) + } + }) + .map(move |(reader, vec)| { + let line = String::from_utf8(vec).unwrap(); + let msg = models::IrcMessage::from_str(&line); + match msg { + Some(msg) => { + println!("{} -> {}", addr, msg.to_string().trim()); + + }, + None => eprintln!("Unhandled message: {} -> {}", addr, line.trim()), + }; + reader + }) }); + // Spawn the future as a concurrent task. - tokio::spawn(handle_conn) + tokio::spawn(socket_reader.then(move |_| { + println!("Connection {} closed", addr); + Ok(()) + })) }); tokio::run(server); diff --git a/src/models.rs b/src/models.rs index 93c6967..8bf4a16 100644 --- a/src/models.rs +++ b/src/models.rs @@ -6,6 +6,11 @@ pub enum IrcCommand { PART, PRIVMSG, WHO, + MODE, + LIST, + CAP, + PASS, + QUIT, } impl IrcCommand { @@ -18,6 +23,11 @@ impl IrcCommand { "PART" => Some(PART), "PRIVMSG" => Some(PRIVMSG), "WHO" => Some(WHO), + "MODE" => Some(MODE), + "CAP" => Some(CAP), + "QUIT" => Some(QUIT), + "LIST" => Some(LIST), + "PASS" => Some(PASS), _ => None, } } diff --git a/src/user.rs b/src/user.rs new file mode 100644 index 0000000..231d748 --- /dev/null +++ b/src/user.rs @@ -0,0 +1,12 @@ +pub struct User { + pub nickname: String, + pub username: String, + pub hostname: String, + pub realname: String, +} + +impl User { + fn to_string(&self) -> String { + format!("{}!{}@{}", self.nickname, self.username, self.hostname) + } +}