diff --git a/examples/dealer_router.rs b/examples/dealer_router.rs new file mode 100644 index 0000000..7584e68 --- /dev/null +++ b/examples/dealer_router.rs @@ -0,0 +1,266 @@ +/* + * This file is part of Tokio ZMQ. + * + * Copyright © 2017 Riley Trautman + * + * Tokio ZMQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tokio ZMQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tokio ZMQ. If not, see . + */ + +#![feature(try_from)] + +extern crate futures; +extern crate tokio_core; +extern crate zmq; +extern crate tokio_zmq; +extern crate log; +extern crate env_logger; + +use std::rc::Rc; +use std::convert::TryInto; +use std::collections::VecDeque; +use std::thread; +use std::env; + +use futures::stream::iter_ok; +use futures::{Future, Stream}; +use tokio_core::reactor::Core; +use tokio_zmq::prelude::*; +use tokio_zmq::{Dealer, Rep, Req, Router, Pub, Sub}; +use tokio_zmq::{Socket, Error}; + +pub struct Stop; + +impl ControlHandler for Stop { + fn should_stop(&self, _: VecDeque) -> bool { + println!("Got stop signal"); + true + } +} + +fn client() { + let mut core = Core::new().unwrap(); + let ctx = Rc::new(zmq::Context::new()); + let req: Req = Socket::new(Rc::clone(&ctx), core.handle()) + .connect("tcp://localhost:5559") + .try_into() + .unwrap(); + + let zpub: Pub = Socket::new(Rc::clone(&ctx), core.handle()) + .bind("tcp://*:5561") + .try_into() + .unwrap(); + + let runner = iter_ok(0..10) + .and_then(|request_nbr| { + let msg = zmq::Message::from_slice(b"Hewwo?").unwrap(); + + let mut multipart = VecDeque::new(); + multipart.push_back(msg); + + println!("Sending 'Hewwo?' for {}", request_nbr); + + let response = req.recv(); + let request = req.send(multipart); + + request.and_then(move |_| { + response.map(move |multipart| (request_nbr, multipart)) + }) + }) + .for_each(|(request_nbr, multipart)| { + for msg in multipart { + if let Some(msg) = msg.as_str() { + println!("Received reply {} {}", request_nbr, msg); + } + } + + Ok(()) + }) + .and_then(|_| { + let msg = zmq::Message::from_slice(b"").unwrap(); + + let mut multipart = VecDeque::new(); + multipart.push_back(msg); + + zpub.send(multipart) + }); + + let res = core.run(runner); + if let Err(e) = res { + println!("client bailed: {:?}", e); + } +} + +fn worker() { + let mut core = Core::new().unwrap(); + let ctx = Rc::new(zmq::Context::new()); + + let rep: Rep = Socket::new(Rc::clone(&ctx), core.handle()) + .connect("tcp://localhost:5560") + .try_into() + .unwrap(); + + let sub: Sub = Socket::new(Rc::clone(&ctx), core.handle()) + .connect("tcp://localhost:5561") + .filter(b"") + .try_into() + .unwrap(); + + let rep = rep.controlled(sub); + + let runner = rep.stream(Stop) + .map(|multipart| { + for msg in multipart { + if let Some(msg) = msg.as_str() { + println!("Received request: {}", msg); + } + } + + let msg = zmq::Message::from_slice(b"Mr Obama???").unwrap(); + let mut multipart = VecDeque::new(); + multipart.push_back(msg); + + multipart + }) + .forward(rep.sink::()); + + let res = core.run(runner); + + if let Err(e) = res { + println!("worker bailed: {:?}", e); + } +} + +fn broker() { + let mut core = Core::new().unwrap(); + let ctx = Rc::new(zmq::Context::new()); + + let router: Router = Socket::new(Rc::clone(&ctx), core.handle()) + .bind("tcp://*:5559") + .try_into() + .unwrap(); + let sub: Sub = Socket::new(Rc::clone(&ctx), core.handle()) + .connect("tcp://localhost:5561") + .filter(b"") + .try_into() + .unwrap(); + let router = router.controlled(sub); + + let dealer: Dealer = Socket::new(Rc::clone(&ctx), core.handle()) + .bind("tcp://*:5560") + .try_into() + .unwrap(); + let sub: Sub = Socket::new(Rc::clone(&ctx), core.handle()) + .connect("tcp://localhost:5561") + .filter(b"") + .try_into() + .unwrap(); + let dealer = dealer.controlled(sub); + + let d2r = dealer + .stream(Stop) + .map(|multipart| { + for msg in &multipart { + if let Some(msg) = msg.as_str() { + println!("Relaying message '{}' to router", msg); + } else { + println!("Relaying unknown message to router"); + } + } + multipart + }) + .forward(router.sink::()); + let r2d = router + .stream(Stop) + .map(|multipart| { + for msg in &multipart { + if let Some(msg) = msg.as_str() { + println!("Relaying message '{}' to dealer", msg); + } else { + println!("Relaying unknown message to dealer"); + } + } + multipart + }) + .forward(dealer.sink::()); + + core.handle().spawn(d2r.map(|_| ()).map_err(|e| { + println!("d2r bailed: {:?}", e) + })); + let res = core.run(r2d); + + if let Err(e) = res { + println!("broker bailed: {:?}", e); + } +} + +#[derive(Debug, PartialEq)] +enum Selection { + All, + Broker, + Worker, + Client, +} + +impl Selection { + fn broker(&self) -> bool { + *self == Selection::All || *self == Selection::Broker + } + + fn worker(&self) -> bool { + *self == Selection::All || *self == Selection::Worker + } + + fn client(&self) -> bool { + *self == Selection::All || *self == Selection::Client + } +} + +fn main() { + env_logger::init().unwrap(); + + let selection = env::var("SELECTION").unwrap_or("all".into()); + + let selection = match selection.as_ref() { + "broker" => Selection::Broker, + "worker" => Selection::Worker, + "client" => Selection::Client, + _ => Selection::All, + }; + + println!("SELECTION: {:?}", selection); + + let mut broker_thread = None; + let mut worker_thread = None; + let mut client_thread = None; + + if selection.broker() { + broker_thread = Some(thread::spawn(broker)); + } + if selection.worker() { + worker_thread = Some(thread::spawn(worker)); + } + if selection.client() { + client_thread = Some(thread::spawn(client)); + } + + if let Some(broker_thread) = broker_thread { + broker_thread.join().unwrap(); + } + if let Some(worker_thread) = worker_thread { + worker_thread.join().unwrap(); + } + if let Some(client_thread) = client_thread { + client_thread.join().unwrap(); + } +} diff --git a/examples/req.rs b/examples/req.rs index c9030d6..18d7b7a 100644 --- a/examples/req.rs +++ b/examples/req.rs @@ -47,7 +47,7 @@ fn main() { .try_into() .unwrap(); - let runner = iter_ok(0..10) + let runner = iter_ok(0..10000) .and_then(|i| { let mut multipart = VecDeque::new(); let msg1 = zmq::Message::from_slice(format!("Hewwo? {}", i).as_bytes()).unwrap(); diff --git a/src/async/future.rs b/src/async/future.rs index 8b695fe..c310707 100644 --- a/src/async/future.rs +++ b/src/async/future.rs @@ -26,7 +26,7 @@ use std::rc::Rc; use zmq; use tokio_core::reactor::PollEvented; use tokio_file_unix::File; -use futures::{Async, Future, Poll}; +use futures::{Async, AsyncSink, Future, Poll}; use futures::task; use error::Error; @@ -99,52 +99,66 @@ impl MultipartRequest { fn send(&mut self) -> Poll<(), Error> { loop { + debug!("MultipartRequest: loop"); let mut multipart = match self.multipart.take() { Some(multipart) => multipart, - None => return Ok(Async::Ready(())), + None => { + debug!("MultipartRequest: breaking loop, no multipart"); + break; + } }; let msg = match multipart.pop_front() { Some(msg) => msg, None => { self.multipart = None; - return Ok(Async::Ready(())); + debug!("MultipartRequest: breaking loop, empty multipart"); + task::current().notify(); + break; } }; let place = if multipart.is_empty() { + debug!("MultipartRequest: Last message"); MsgPlace::Last } else { + debug!("MultipartRequest: Nth message"); MsgPlace::Nth }; match self.send_msg(msg, place)? { - Async::Ready(()) => (), - Async::NotReady => { - // In the future, push_front the failed message - () - } - } + AsyncSink::Ready => { + debug!("MultipartRequest: Sent!"); - if multipart.is_empty() { - return Ok(Async::Ready(())); + if multipart.is_empty() { + debug!("MultipartRequest: breaking loop"); + break; + } + } + AsyncSink::NotReady(msg) => { + multipart.push_front(msg); + } } self.multipart = Some(multipart); } + + Ok(Async::Ready(())) } - fn send_msg(&mut self, msg: zmq::Message, place: MsgPlace) -> Poll<(), Error> { + fn send_msg( + &mut self, + msg: zmq::Message, + place: MsgPlace, + ) -> Result, Error> { + debug!("MultipartRequest: send_msg"); let events = self.sock.get_events()? as i16; if events & zmq::POLLOUT == 0 { - if events & zmq::POLLIN != 0 { - self.file.need_read(); - } else { - self.file.need_write(); - } + debug!("MultipartRequest: need_write()"); + self.file.need_write(); - return Ok(Async::NotReady); + return Ok(AsyncSink::NotReady(msg)); } let flags = zmq::DONTWAIT | @@ -155,8 +169,12 @@ impl MultipartRequest { }; match self.sock.send_msg(msg, flags) { - Ok(_) => Ok(Async::Ready(())), - Err(e @ zmq::Error::EAGAIN) => Err(e.into()), + Ok(_) => Ok(AsyncSink::Ready), + Err(e @ zmq::Error::EAGAIN) => { + // return message in future + debug!("MultipartRequest: EAGAIN"); + Err(e.into()) + } Err(e) => Err(e.into()), } } @@ -167,13 +185,14 @@ impl MultipartRequest { let events = self.sock.get_events()? as i16; if events & zmq::POLLOUT != 0 { // manually schedule a wakeup and procede - debug!("Write ready, but file doesn't think so"); + debug!("MultipartRequest: Write ready, but file doesn't think so"); task::current().notify(); } else { return Ok(false); } if events & zmq::POLLIN != 0 { + debug!("MultipartRequest: need_read()"); self.file.need_read(); } } @@ -187,6 +206,7 @@ impl Future for MultipartRequest { type Error = Error; fn poll(&mut self) -> Poll { + debug!("MultipartRequest: in poll"); if self.check_write()? { self.send() } else { @@ -253,44 +273,61 @@ impl MultipartResponse { } fn recv(&mut self) -> Poll { + debug!("MultipartResponse: recv"); let events = self.sock.get_events()? as i16; if events & zmq::POLLIN == 0 { - if events & zmq::POLLOUT != 0 { - self.file.need_write(); - } else { - self.file.need_read(); - } + debug!("MultipartResponse: need_read()"); + self.file.need_read(); + debug!("MultipartResponse: leaving recv"); return Ok(Async::NotReady); } - match self.recv_msg()? { - Async::Ready(msg) => { - let mut multipart = self.multipart.take().unwrap_or(VecDeque::new()); + let mut first = true; - let more = msg.get_more(); + loop { + debug!("MultipartResponse: loop"); + match self.recv_msg()? { + Async::Ready(msg) => { + first = false; + let mut multipart = self.multipart.take().unwrap_or(VecDeque::new()); - multipart.push_back(msg); + let more = msg.get_more(); - if !more { - return Ok(Async::Ready(multipart)); - } + multipart.push_back(msg); - task::current().notify(); - self.multipart = Some(multipart); - Ok(Async::NotReady) + if !more { + debug!("MultipartResponse: Done receiving, returning multipart"); + return Ok(Async::Ready(multipart)); + } + + debug!("MultipartResponse: Waiting on more"); + self.multipart = Some(multipart); + } + Async::NotReady => { + if first { + debug!("MultipartResponse: leaving recv, not ready"); + return Ok(Async::NotReady); + } + } } - Async::NotReady => Ok(Async::NotReady), } } fn recv_msg(&mut self) -> Poll { + debug!("MultipartResponse: recv_msg"); let mut msg = zmq::Message::new()?; match self.sock.recv(&mut msg, zmq::DONTWAIT) { - Ok(_) => Ok(Async::Ready(msg)), - Err(zmq::Error::EAGAIN) => Ok(Async::NotReady), + Ok(_) => { + debug!("MultipartResponse: received: {:?}", msg.as_str()); + Ok(Async::Ready(msg)) + } + Err(zmq::Error::EAGAIN) => { + debug!("MultipartResponse: EAGAIN"); + Ok(Async::NotReady) + } Err(e) => Err(e.into()), } } @@ -300,7 +337,7 @@ impl MultipartResponse { let events = self.sock.get_events()? as i16; if events & zmq::POLLIN != 0 { // manually schedule a wakeup and procede - debug!("Read ready, but file doesn't think so"); + debug!("MultipartResponse: Read ready, but file doesn't think so"); task::current().notify(); } else { return Ok(false); @@ -320,6 +357,7 @@ impl Future for MultipartResponse { type Error = Error; fn poll(&mut self) -> Poll { + debug!("MultipartResponse: In poll"); if self.check_read()? { self.recv() } else { diff --git a/src/async/sink.rs b/src/async/sink.rs index fc96cd0..c2b795b 100644 --- a/src/async/sink.rs +++ b/src/async/sink.rs @@ -26,10 +26,10 @@ use std::rc::Rc; use zmq; use tokio_core::reactor::PollEvented; use tokio_file_unix::File; -use futures::{Async, AsyncSink, Poll, Sink, StartSend}; -use futures::task; +use futures::{Async, AsyncSink, Future, Poll, Sink, StartSend}; -use super::{MsgPlace, Multipart}; +use super::Multipart; +use async::future::MultipartRequest; use error::Error; use file::ZmqFile; @@ -80,10 +80,10 @@ pub struct MultipartSink where E: From, { + request: Option, sock: Rc, // Handles notifications to/from the event loop file: Rc>>, - multipart: Option, phantom: PhantomData, } @@ -93,144 +93,28 @@ where { pub fn new(sock: Rc, file: Rc>>) -> Self { MultipartSink { + request: None, sock: sock, file: file, - multipart: None, phantom: PhantomData, } } - fn send_msg( - &mut self, - msg: zmq::Message, - place: MsgPlace, - ) -> Result, E> { - debug!("MultipartSink: In send: {:?}", msg.as_str()); - // Get the events currently waiting on the socket - let events = self.sock.get_events().map_err(Error::from)? as i16; - debug!("MultipartSink: Got events"); - - // Double check that the socket is ready for writing - if events & zmq::POLLOUT == 0 { - if events & zmq::POLLIN != 0 { - self.file.need_read(); - debug!( - "MultipartSink: Events does not indicate POLLOUT: e{} != p{}", - events, - zmq::POLLOUT - ); - return Ok(AsyncSink::NotReady(msg)); - } else { - self.file.need_write(); - debug!( - "MultipartSink: Events does not indicate POLLOUT: e{} != p{}", - events, - zmq::POLLOUT - ); - return Ok(AsyncSink::NotReady(msg)); - } - } - - let flags = zmq::DONTWAIT | - if place == MsgPlace::Last { - debug!("MultipartSink: flags: DONTWAIT | 0"); - 0 - } else { - debug!("MultipartSink: flags: DONTWAIT | SNDMORE"); - zmq::SNDMORE - }; - - match self.sock.send_msg(msg, flags) { - Ok(_) => { - debug!("MultipartSink: Sent!"); - Ok(AsyncSink::Ready) - } - Err(zmq::Error::EAGAIN) => { - /* I'd like to have the following code in place, but the Rust zmq high-level - * bindings don't return the message you just tried to send if it fails to send. - * For now, we bubble the error. - * - * // If EAGAIN, the socket is busy. This shouldn't happend because we have already - * // witnessed that the socket is ready for writing. - * Ok(AsyncSink::NotReady(msg)) - */ - debug!("MultipartSink: EAGAIN"); - let e = zmq::Error::EAGAIN; - let e: Error = e.into(); - Err(e.into()) - } - Err(e) => { - debug!("MultipartSink: Error: {}", e); - let e: Error = e.into(); - Err(e.into()) - } - } - } - - fn flush(&mut self) -> Result, E> { - debug!("MultipartSink: In flush"); - loop { - if let Some(mut multipart) = self.multipart.take() { - if let Some(curr_msg) = multipart.pop_front() { - debug!("MultipartSink: Sending current message"); - - let msg_place = if multipart.is_empty() { - MsgPlace::Last - } else { - MsgPlace::Nth - }; - - match self.send_msg(curr_msg, msg_place)? { - AsyncSink::Ready => { - debug!("MultipartSink: self.send success!"); - - if !multipart.is_empty() { - self.multipart = Some(multipart); - continue; - // return Ok(Async::NotReady); - } - break; - } - AsyncSink::NotReady(curr_msg) => { - debug!("MultipartSink: Failed send"); - // If we couldn't send the current message, put it back and return NotReady - multipart.push_front(curr_msg); - self.multipart = Some(multipart); - continue; - // return Ok(Async::NotReady); - } - } - } else { - self.multipart = None; - break; - } - } else { - break; + fn poll_request(&mut self, mut request: MultipartRequest) -> Poll<(), E> { + match request.poll()? { + Async::Ready(()) => Ok(Async::Ready(())), + Async::NotReady => { + self.request = Some(request); + Ok(Async::NotReady) } } - - debug!("MultipartSink: Ready!"); - Ok(Async::Ready(())) } - fn check_write(&mut self) -> Result { - if let Async::NotReady = self.file.poll_write() { - // Get the events currently waiting on the socket - let events = self.sock.get_events().map_err(Error::from)? as i16; - if events & zmq::POLLOUT != 0 { - // manually schedule a wakeup and procede - debug!("Write ready, but file doesn't think so"); - task::current().notify(); - } else { - return Ok(false); - } - - if events & zmq::POLLIN != 0 { - self.file.need_read(); - } - } + fn make_request(&mut self, multipart: Multipart) { + let sock = Rc::clone(&self.sock); + let file = Rc::clone(&self.file); - Ok(true) + self.request = Some(MultipartRequest::new(sock, file, multipart)); } } @@ -246,39 +130,30 @@ where multipart: Self::SinkItem, ) -> StartSend { debug!("MultipartSink: start_send"); - if self.check_write()? { - if self.multipart.is_none() { - debug!("MultipartSink: Set multipart, ready!"); - self.multipart = Some(multipart); - self.file.need_write(); - - Ok(AsyncSink::Ready) - } else { - debug!("MultipartSink: not ready"); - match self.flush()? { - Async::Ready(()) => { - debug!("MultipartSink: Flushed, ready now"); - self.multipart = Some(multipart); + if let Some(request) = self.request.take() { + match self.poll_request(request)? { + Async::Ready(()) => { + self.make_request(multipart); + self.file.need_write(); Ok(AsyncSink::Ready) } - Async::NotReady => { - debug!("MultipartSink: still not ready"); - Ok(AsyncSink::NotReady(multipart)) - } - } + Async::NotReady => Ok(AsyncSink::NotReady(multipart)), } } else { - Ok(AsyncSink::NotReady(multipart)) + self.make_request(multipart); + self.file.need_write(); + + Ok(AsyncSink::Ready) } } fn poll_complete(&mut self) -> Poll<(), Self::SinkError> { debug!("MultipartSink: poll_complete"); - if self.check_write()? { - self.flush() + if let Some(request) = self.request.take() { + self.poll_request(request) } else { - Ok(Async::NotReady) + Ok(Async::Ready(())) } } } diff --git a/src/async/stream.rs b/src/async/stream.rs index 2117a6d..c754879 100644 --- a/src/async/stream.rs +++ b/src/async/stream.rs @@ -101,6 +101,7 @@ impl Stream for MultipartStream { type Error = Error; fn poll(&mut self) -> Poll, Error> { + debug!("MultipartStream: In poll"); if let Some(response) = self.response.take() { self.poll_response(response) } else { @@ -171,6 +172,7 @@ where /// If the control stream is ready with a Multipart, use the `ControlHandler` to /// determine if the producting stream should be stopped. fn poll(&mut self) -> Poll, Error> { + debug!("ControlledStream: in poll"); let stop = match self.control.poll()? { Async::NotReady => false, Async::Ready(None) => true, diff --git a/src/lib.rs b/src/lib.rs index 5bacb9f..db7f78e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -114,6 +114,6 @@ pub mod prelude; pub use async::ControlHandler; pub use self::error::Error; pub use socket::Socket; -pub use socket::{Rep, Req, Pub, Sub, Push, Pull, Xpub, Xsub, Pair}; -pub use socket::{RepControlled, SubControlled, PullControlled, XpubControlled, XsubControlled, - PairControlled}; +pub use socket::{Dealer, Rep, Req, Router, Pub, Sub, Push, Pull, Xpub, Xsub, Pair}; +pub use socket::{DealerControlled, RepControlled, RouterControlled, SubControlled, PullControlled, + XpubControlled, XsubControlled, PairControlled}; diff --git a/src/prelude.rs b/src/prelude.rs index d5618ed..3cd8940 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -18,5 +18,6 @@ */ //! Re-export all important traits to make developing with this library easier -pub use socket::{AsSocket, ControlledStreamSocket, FutureSocket, SinkSocket, StreamSocket}; +pub use socket::{AsControlledSocket, AsSocket, ControlledSinkSocket, ControlledStreamSocket, + FutureSocket, SinkSocket, StreamSocket}; pub use async::ControlHandler; diff --git a/src/socket/mod.rs b/src/socket/mod.rs index 47674c2..3e53b95 100644 --- a/src/socket/mod.rs +++ b/src/socket/mod.rs @@ -19,33 +19,28 @@ //! This module contains useful traits and types for working with ZeroMQ Sockets. +mod config; +mod types; + +pub use self::types::{Dealer, DealerControlled}; +pub use self::types::{Pair, PairControlled}; +pub use self::types::{Pull, PullControlled}; +pub use self::types::{Rep, RepControlled}; +pub use self::types::{Router, RouterControlled}; +pub use self::types::{Sub, SubControlled}; +pub use self::types::{Xpub, XpubControlled}; +pub use self::types::{Xsub, XsubControlled}; +pub use self::types::Pub; +pub use self::types::Push; +pub use self::types::Req; +pub use self::config::SockConfig; + use std::rc::Rc; use zmq; use tokio_core::reactor::{Handle, PollEvented}; use tokio_file_unix::File; -pub mod config; -pub mod rep; -pub mod req; -pub mod zpub; -pub mod sub; -pub mod push; -pub mod pull; -pub mod xpub; -pub mod xsub; -pub mod pair; - -pub use self::rep::{Rep, RepControlled}; -pub use self::req::Req; -pub use self::zpub::Pub; -pub use self::sub::{Sub, SubControlled}; -pub use self::push::Push; -pub use self::pull::{Pull, PullControlled}; -pub use self::xpub::{Xpub, XpubControlled}; -pub use self::xsub::{Xsub, XsubControlled}; -pub use self::pair::{Pair, PairControlled}; - use self::config::SockConfigStart; use async::{ControlledStream, ControlHandler, Multipart, MultipartRequest, MultipartResponse, MultipartSink, MultipartStream}; @@ -62,16 +57,19 @@ pub trait AsSocket { fn into_socket(self) -> Socket; } -/// This trait is used for types wrapping `ControlledSocket`s. It requires implementing only one -/// method, `socket(&self)`, which is analogous to the `AsSocket` trait's `socket(&self)` method. -pub trait ControlledStreamSocket -where - H: ControlHandler, -{ +/// Analogous to the AsSocket trait, but for Controlled sockets. +pub trait AsControlledSocket { /// Any implementing type must have a method of getting a reference to the inner /// `ControlledSocket`. fn socket(&self) -> &ControlledSocket; +} +/// This trait is used for types wrapping `ControlledSocket`s. It depends on the type implementing +/// AsControlledSocket, which is analogous to the `AsSocket` trait's `socket(&self)` method. +pub trait ControlledStreamSocket: AsControlledSocket +where + H: ControlHandler, +{ /// Receive a single multipart message from the socket. fn recv(&self) -> MultipartResponse { self.socket().recv() @@ -86,10 +84,7 @@ where /// In addition to having Streams, some sockets also have Sinks. Every controlled socket has a /// stream, but to give Sink functionality to those that have Sinks as well, this trait is /// implemented. -pub trait ControlledSinkSocket: ControlledStreamSocket -where - H: ControlHandler, -{ +pub trait ControlledSinkSocket: AsControlledSocket { /// Send a single multipart message to the socket. /// /// For example usage of `send`, see `SinkSocket`'s send definition. @@ -108,6 +103,8 @@ where } } +/// This trait provides the basic Stream support for ZeroMQ Sockets. It depends on AsSocket, but +/// provides implementations for `sink` and `recv`. pub trait StreamSocket: AsSocket { /// Receive a single multipart message from the socket. /// @@ -201,6 +198,8 @@ pub trait StreamSocket: AsSocket { } } +/// This trait provides the basic Sink support for ZeroMQ Sockets. It depends on AsSocket and +/// provides the `send` and `sink` methods. pub trait SinkSocket: AsSocket { /// Send a single multipart message to the socket. /// @@ -293,6 +292,9 @@ pub trait SinkSocket: AsSocket { } } +/// This trait is used for socket types that don't really fit in the context of `Stream` or `Sink`. +/// Typically interaction with these sockets is one-off. This trait provides implementations for +/// `send` and `recv`. pub trait FutureSocket: AsSocket { /// Send a single multipart message to the socket. /// diff --git a/src/socket/pair.rs b/src/socket/pair.rs deleted file mode 100644 index 4311749..0000000 --- a/src/socket/pair.rs +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::PairConfig; -use socket::{AsSocket, ControlledSocket, ControlledSinkSocket, ControlledStreamSocket, - ControlHandler, SinkSocket, Socket, StreamSocket}; -use error::Error; - -pub struct Pair { - inner: Socket, -} - -impl Pair { - pub fn controlled(self, control: S) -> PairControlled - where - S: StreamSocket, - { - PairControlled { inner: self.inner.controlled(control) } - } -} - -impl AsSocket for Pair { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl StreamSocket for Pair {} -impl SinkSocket for Pair {} - -impl<'a> TryFrom> for Pair { - type Error = Error; - - fn try_from(conf: PairConfig<'a>) -> Result { - Ok(Pair { inner: conf.build(zmq::PAIR)? }) - } -} - -pub struct PairControlled { - inner: ControlledSocket, -} - -impl ControlledStreamSocket for PairControlled -where - H: ControlHandler, -{ - fn socket(&self) -> &ControlledSocket { - &self.inner - } -} - -impl ControlledSinkSocket for PairControlled -where - H: ControlHandler, -{ -} diff --git a/src/socket/pull.rs b/src/socket/pull.rs deleted file mode 100644 index 920f069..0000000 --- a/src/socket/pull.rs +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::SockConfig; -use socket::{AsSocket, ControlledSocket, ControlledStreamSocket, ControlHandler, Socket, - StreamSocket}; -use error::Error; - -pub struct Pull { - inner: Socket, -} - -impl Pull { - pub fn controlled(self, control: S) -> PullControlled - where - S: StreamSocket, - { - PullControlled { inner: self.inner.controlled(control) } - } -} - -impl AsSocket for Pull { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl StreamSocket for Pull {} - -impl<'a> TryFrom> for Pull { - type Error = Error; - - fn try_from(conf: SockConfig<'a>) -> Result { - Ok(Pull { inner: conf.build(zmq::PULL)? }) - } -} - -pub struct PullControlled { - inner: ControlledSocket, -} - -impl ControlledStreamSocket for PullControlled -where - H: ControlHandler, -{ - fn socket(&self) -> &ControlledSocket { - &self.inner - } -} diff --git a/src/socket/push.rs b/src/socket/push.rs deleted file mode 100644 index bab42d6..0000000 --- a/src/socket/push.rs +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::SockConfig; -use socket::{AsSocket, SinkSocket, Socket}; -use error::Error; - -pub struct Push { - inner: Socket, -} - -impl AsSocket for Push { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl SinkSocket for Push {} - -impl<'a> TryFrom> for Push { - type Error = Error; - - fn try_from(conf: SockConfig<'a>) -> Result { - Ok(Push { inner: conf.build(zmq::PUSH)? }) - } -} diff --git a/src/socket/rep.rs b/src/socket/rep.rs deleted file mode 100644 index e352cb0..0000000 --- a/src/socket/rep.rs +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::SockConfig; -use socket::{AsSocket, ControlledSocket, ControlledSinkSocket, ControlledStreamSocket, - ControlHandler, SinkSocket, Socket, StreamSocket}; -use error::Error; - -pub struct Rep { - inner: Socket, -} - -impl Rep { - pub fn controlled(self, control: S) -> RepControlled - where - S: StreamSocket, - { - RepControlled { inner: self.inner.controlled(control) } - } -} - -impl AsSocket for Rep { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl StreamSocket for Rep {} -impl SinkSocket for Rep {} - -impl<'a> TryFrom> for Rep { - type Error = Error; - - fn try_from(conf: SockConfig<'a>) -> Result { - Ok(Rep { inner: conf.build(zmq::REP)? }) - } -} - -pub struct RepControlled { - inner: ControlledSocket, -} - -impl ControlledStreamSocket for RepControlled -where - H: ControlHandler, -{ - fn socket(&self) -> &ControlledSocket { - &self.inner - } -} - -impl ControlledSinkSocket for RepControlled -where - H: ControlHandler, -{ -} diff --git a/src/socket/req.rs b/src/socket/req.rs deleted file mode 100644 index 75d94a6..0000000 --- a/src/socket/req.rs +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::SockConfig; -use socket::{AsSocket, FutureSocket, Socket}; -use error::Error; - -pub struct Req { - inner: Socket, -} - -impl AsSocket for Req { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl FutureSocket for Req {} - -impl<'a> TryFrom> for Req { - type Error = Error; - - fn try_from(conf: SockConfig<'a>) -> Result { - Ok(Req { inner: conf.build(zmq::REQ)? }) - } -} diff --git a/src/socket/sub.rs b/src/socket/sub.rs deleted file mode 100644 index a8283d2..0000000 --- a/src/socket/sub.rs +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::SubConfig; -use socket::{AsSocket, ControlledSocket, ControlledStreamSocket, ControlHandler, Socket, - StreamSocket}; -use error::Error; - -pub struct Sub { - inner: Socket, -} - -impl Sub { - pub fn controlled(self, control: S) -> SubControlled - where - S: StreamSocket, - { - SubControlled { inner: self.inner.controlled(control) } - } -} - -impl AsSocket for Sub { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl StreamSocket for Sub {} - -impl<'a> TryFrom> for Sub { - type Error = Error; - - fn try_from(conf: SubConfig<'a>) -> Result { - Ok(Sub { inner: conf.build(zmq::SUB)? }) - } -} - -pub struct SubControlled { - inner: ControlledSocket, -} - -impl ControlledStreamSocket for SubControlled -where - H: ControlHandler, -{ - fn socket(&self) -> &ControlledSocket { - &self.inner - } -} diff --git a/src/socket/types.rs b/src/socket/types.rs new file mode 100644 index 0000000..fc1fb9f --- /dev/null +++ b/src/socket/types.rs @@ -0,0 +1,580 @@ +/* + * This file is part of Tokio ZMQ. + * + * Copyright © 2017 Riley Trautman + * + * Tokio ZMQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tokio ZMQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tokio ZMQ. If not, see . + */ + +use std::convert::TryFrom; + +use zmq; + +use socket::config::{PairConfig, SockConfig, SubConfig}; +use prelude::*; +use socket::{ControlledSocket, Socket}; +use error::Error; + +/* -------------------------------------------------------------------------- */ + +/// The DEALER SocketType wrapper type. +/// +/// Dealer implements StreamSocket and SinkSocket, and has an associated controlled variant. +pub struct Dealer { + inner: Socket, +} + +impl Dealer { + /// Construct a controled version of the Dealer socket. + pub fn controlled(self, control: S) -> DealerControlled + where + S: StreamSocket, + { + DealerControlled { inner: self.inner.controlled(control) } + } +} + +impl AsSocket for Dealer { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl StreamSocket for Dealer {} +impl SinkSocket for Dealer {} + +impl<'a> TryFrom> for Dealer { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Dealer { inner: conf.build(zmq::DEALER)? }) + } +} + +/// The controlled variant of Dealer +pub struct DealerControlled { + inner: ControlledSocket, +} + +impl AsControlledSocket for DealerControlled { + fn socket(&self) -> &ControlledSocket { + &self.inner + } +} + +impl ControlledStreamSocket for DealerControlled +where + H: ControlHandler, +{ +} + +impl ControlledSinkSocket for DealerControlled {} + +/* -------------------------------------------------------------------------- */ + +/// The PAIR SocketType wrapper type. +/// +/// Pair implements StreamSocket and SinkSocket, and has an associated controlled variant. +pub struct Pair { + inner: Socket, +} + +impl Pair { + /// Construct a controlled variant of the Pair socket + pub fn controlled(self, control: S) -> PairControlled + where + S: StreamSocket, + { + PairControlled { inner: self.inner.controlled(control) } + } +} + +impl AsSocket for Pair { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl StreamSocket for Pair {} +impl SinkSocket for Pair {} + +impl<'a> TryFrom> for Pair { + type Error = Error; + + fn try_from(conf: PairConfig<'a>) -> Result { + Ok(Pair { inner: conf.build(zmq::PAIR)? }) + } +} + +/// The controlled variant of Pair +pub struct PairControlled { + inner: ControlledSocket, +} + +impl AsControlledSocket for PairControlled { + fn socket(&self) -> &ControlledSocket { + &self.inner + } +} + +impl ControlledStreamSocket for PairControlled +where + H: ControlHandler, +{ +} + +impl ControlledSinkSocket for PairControlled {} + +/* -------------------------------------------------------------------------- */ + +/// The PUB SocketType wrapper type +/// +/// Pub implements SinkSocket. +pub struct Pub { + inner: Socket, +} + +impl AsSocket for Pub { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl SinkSocket for Pub {} + +impl<'a> TryFrom> for Pub { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Pub { inner: conf.build(zmq::PUB)? }) + } +} + +/* -------------------------------------------------------------------------- */ + +/// The PULL SocketType wrapper type +/// +/// Pull implements StreamSocket, and has an associated controlled variant. +pub struct Pull { + inner: Socket, +} + +impl Pull { + /// Construct a controlled variant of the Pull socket + pub fn controlled(self, control: S) -> PullControlled + where + S: StreamSocket, + { + PullControlled { inner: self.inner.controlled(control) } + } +} + +impl AsSocket for Pull { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl StreamSocket for Pull {} + +impl<'a> TryFrom> for Pull { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Pull { inner: conf.build(zmq::PULL)? }) + } +} + +/// The controlled variant of Pull +pub struct PullControlled { + inner: ControlledSocket, +} + +impl AsControlledSocket for PullControlled { + fn socket(&self) -> &ControlledSocket { + &self.inner + } +} + +impl ControlledStreamSocket for PullControlled +where + H: ControlHandler, +{ +} + +/* -------------------------------------------------------------------------- */ + +/// The PUSH SocketType wrapper type +/// +/// Push implements SinkSocket. +pub struct Push { + inner: Socket, +} + +impl AsSocket for Push { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl SinkSocket for Push {} + +impl<'a> TryFrom> for Push { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Push { inner: conf.build(zmq::PUSH)? }) + } +} + +/* -------------------------------------------------------------------------- */ + +/// The REP SocketType wrapper type +/// +/// Rep implements StreamSocket and SinkSocket, and has an associated controlled variant. +pub struct Rep { + inner: Socket, +} + +impl Rep { + /// Construct a controlled variant of the Rep socket + pub fn controlled(self, control: S) -> RepControlled + where + S: StreamSocket, + { + RepControlled { inner: self.inner.controlled(control) } + } +} + +impl AsSocket for Rep { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl StreamSocket for Rep {} +impl SinkSocket for Rep {} + +impl<'a> TryFrom> for Rep { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Rep { inner: conf.build(zmq::REP)? }) + } +} + +/// The controlled variant of Rep +pub struct RepControlled { + inner: ControlledSocket, +} + +impl AsControlledSocket for RepControlled { + fn socket(&self) -> &ControlledSocket { + &self.inner + } +} + +impl ControlledStreamSocket for RepControlled +where + H: ControlHandler, +{ +} + +impl ControlledSinkSocket for RepControlled {} + +/* -------------------------------------------------------------------------- */ + +/// The REQ SocketType wrapper type +/// +/// Req implements FutureSocket. +pub struct Req { + inner: Socket, +} + +impl AsSocket for Req { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl FutureSocket for Req {} + +impl<'a> TryFrom> for Req { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Req { inner: conf.build(zmq::REQ)? }) + } +} + +/* -------------------------------------------------------------------------- */ + +/// The ROUTER SocketType wrapper type +/// +/// Router implements StreamSocket and SinkSocket, and has an associated controlled variant. +pub struct Router { + inner: Socket, +} + +impl Router { + /// Construct a controlled variant of the Router socket + pub fn controlled(self, control: S) -> RouterControlled + where + S: StreamSocket, + { + RouterControlled { inner: self.inner.controlled(control) } + } +} + +impl AsSocket for Router { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl StreamSocket for Router {} +impl SinkSocket for Router {} + +impl<'a> TryFrom> for Router { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Router { inner: conf.build(zmq::ROUTER)? }) + } +} + +/// The controlled variant of Router +pub struct RouterControlled { + inner: ControlledSocket, +} + +impl AsControlledSocket for RouterControlled { + fn socket(&self) -> &ControlledSocket { + &self.inner + } +} + +impl ControlledStreamSocket for RouterControlled +where + H: ControlHandler, +{ +} + +impl ControlledSinkSocket for RouterControlled {} + +/* -------------------------------------------------------------------------- */ + +/// The SUB SocketType wrapper type +/// +/// Sub implements StreamSocket, and has an associated controlled variant. +pub struct Sub { + inner: Socket, +} + +impl Sub { + /// Construct a controlled variant of the Sub socket + pub fn controlled(self, control: S) -> SubControlled + where + S: StreamSocket, + { + SubControlled { inner: self.inner.controlled(control) } + } +} + +impl AsSocket for Sub { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl StreamSocket for Sub {} + +impl<'a> TryFrom> for Sub { + type Error = Error; + + fn try_from(conf: SubConfig<'a>) -> Result { + Ok(Sub { inner: conf.build(zmq::SUB)? }) + } +} + +/// The controlled variant of Sub. +pub struct SubControlled { + inner: ControlledSocket, +} + +impl AsControlledSocket for SubControlled { + fn socket(&self) -> &ControlledSocket { + &self.inner + } +} + +impl ControlledStreamSocket for SubControlled +where + H: ControlHandler, +{ +} + +/* -------------------------------------------------------------------------- */ + +/// The XPUB SocketType wrapper type +/// +/// Xpub implements StreamSocket and SinkSocket, and has an associated controlled variant. +pub struct Xpub { + inner: Socket, +} + +impl Xpub { + /// Construct a controlled variant of the Xpub socket + pub fn controlled(self, control: S) -> XpubControlled + where + S: StreamSocket, + { + XpubControlled { inner: self.inner.controlled(control) } + } +} + +impl AsSocket for Xpub { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl StreamSocket for Xpub {} +impl SinkSocket for Xpub {} + +impl<'a> TryFrom> for Xpub { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Xpub { inner: conf.build(zmq::XPUB)? }) + } +} + +/// The controlled variant of Xpub +pub struct XpubControlled { + inner: ControlledSocket, +} + +impl AsControlledSocket for XpubControlled { + fn socket(&self) -> &ControlledSocket { + &self.inner + } +} + +impl ControlledStreamSocket for XpubControlled +where + H: ControlHandler, +{ +} + +impl ControlledSinkSocket for XpubControlled {} + +/* -------------------------------------------------------------------------- */ + +/// The XSUB SocketType wrapper type +/// +/// Xsub implements StreamSocket and SinkSocket, and has an associated controlled variant. +pub struct Xsub { + inner: Socket, +} + +impl Xsub { + /// Construct a controlled variant of the Xsub socket + pub fn control(self, control: S) -> XsubControlled + where + S: StreamSocket, + { + XsubControlled { inner: self.inner.controlled(control) } + } +} + +impl AsSocket for Xsub { + fn socket(&self) -> &Socket { + &self.inner + } + + fn into_socket(self) -> Socket { + self.inner + } +} + +impl StreamSocket for Xsub {} +impl SinkSocket for Xsub {} + +impl<'a> TryFrom> for Xsub { + type Error = Error; + + fn try_from(conf: SockConfig<'a>) -> Result { + Ok(Xsub { inner: conf.build(zmq::XSUB)? }) + } +} + +/// The controlled variant of Xsub +pub struct XsubControlled { + inner: ControlledSocket, +} + +impl AsControlledSocket for XsubControlled { + fn socket(&self) -> &ControlledSocket { + &self.inner + } +} + +impl ControlledStreamSocket for XsubControlled +where + H: ControlHandler, +{ +} + +impl ControlledSinkSocket for XsubControlled {} diff --git a/src/socket/xpub.rs b/src/socket/xpub.rs deleted file mode 100644 index fdd6d8c..0000000 --- a/src/socket/xpub.rs +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::SockConfig; -use socket::{AsSocket, ControlledSocket, ControlledSinkSocket, ControlledStreamSocket, - ControlHandler, SinkSocket, Socket, StreamSocket}; -use error::Error; - -pub struct Xpub { - inner: Socket, -} - -impl Xpub { - pub fn controlled(self, control: S) -> XpubControlled - where - S: StreamSocket, - { - XpubControlled { inner: self.inner.controlled(control) } - } -} - -impl AsSocket for Xpub { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl StreamSocket for Xpub {} -impl SinkSocket for Xpub {} - -impl<'a> TryFrom> for Xpub { - type Error = Error; - - fn try_from(conf: SockConfig<'a>) -> Result { - Ok(Xpub { inner: conf.build(zmq::XPUB)? }) - } -} - -pub struct XpubControlled { - inner: ControlledSocket, -} - -impl ControlledStreamSocket for XpubControlled -where - H: ControlHandler, -{ - fn socket(&self) -> &ControlledSocket { - &self.inner - } -} - -impl ControlledSinkSocket for XpubControlled -where - H: ControlHandler, -{ -} diff --git a/src/socket/xsub.rs b/src/socket/xsub.rs deleted file mode 100644 index d1ae6cc..0000000 --- a/src/socket/xsub.rs +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::SockConfig; -use socket::{AsSocket, ControlledSocket, ControlledSinkSocket, ControlledStreamSocket, - ControlHandler, SinkSocket, Socket, StreamSocket}; -use error::Error; - -pub struct Xsub { - inner: Socket, -} - -impl Xsub { - pub fn control(self, control: S) -> XsubControlled - where - S: StreamSocket, - { - XsubControlled { inner: self.inner.controlled(control) } - } -} - -impl AsSocket for Xsub { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl StreamSocket for Xsub {} -impl SinkSocket for Xsub {} - -impl<'a> TryFrom> for Xsub { - type Error = Error; - - fn try_from(conf: SockConfig<'a>) -> Result { - Ok(Xsub { inner: conf.build(zmq::XSUB)? }) - } -} - -pub struct XsubControlled { - inner: ControlledSocket, -} - -impl ControlledStreamSocket for XsubControlled -where - H: ControlHandler, -{ - fn socket(&self) -> &ControlledSocket { - &self.inner - } -} - -impl ControlledSinkSocket for XsubControlled -where - H: ControlHandler, -{ -} diff --git a/src/socket/zpub.rs b/src/socket/zpub.rs deleted file mode 100644 index 4ad6d12..0000000 --- a/src/socket/zpub.rs +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Tokio ZMQ. - * - * Copyright © 2017 Riley Trautman - * - * Tokio ZMQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tokio ZMQ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tokio ZMQ. If not, see . - */ - -use std::convert::TryFrom; - -use zmq; - -use socket::config::SockConfig; -use socket::{AsSocket, SinkSocket, Socket}; -use error::Error; - -pub struct Pub { - inner: Socket, -} - -impl AsSocket for Pub { - fn socket(&self) -> &Socket { - &self.inner - } - - fn into_socket(self) -> Socket { - self.inner - } -} - -impl SinkSocket for Pub {} - -impl<'a> TryFrom> for Pub { - type Error = Error; - - fn try_from(conf: SockConfig<'a>) -> Result { - Ok(Pub { inner: conf.build(zmq::PUB)? }) - } -}