diff --git a/.travis.yml b/.travis.yml index 4b920a0..b374572 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,9 @@ before_script: - (test -x $HOME/.cargo/bin/cargo-cache || cargo install cargo-cache) - (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.3" mdbook) script: - - cargo test --all-targets --no-run - - cargo test --all - - cargo test --examples + - cargo test --all-targets --all-features --no-run + - cargo test --all --all-features + - cargo test --examples --all-features - cargo fmt --all -- --check - cargo clippy --all-targets -- -D warnings - mdbook build libzmq-book diff --git a/README.md b/README.md index ffbd077..dd84373 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,9 @@ A strict subset of ØMQ with an ergonomic API. -# Versioning & Stability Guarantees -**Expect breaking changes with each release until `0.2`**. After that, expect breaking changes only on minor -version until `1.0`. Furthermore, since a large part of the library relies on ØMQ's DRAFT API, -they will have to be stabilized before the 1.0 version is released. - ```toml [dependencies] -libzmq = "0.1.24" +libzmq = "0.2" ``` # Dead Simple Sample diff --git a/libzmq-book/src/examples/secure_req_rep.md b/libzmq-book/src/examples/secure_req_rep.md index 8e0342e..d24b742 100644 --- a/libzmq-book/src/examples/secure_req_rep.md +++ b/libzmq-book/src/examples/secure_req_rep.md @@ -5,14 +5,17 @@ For a public `TCP` connection, its a must. Let's fix that by adapting the previous example. This time we will the `CURVE` mechanism, which is a public-key crypto. -Depending on your setup, it should have little to no overhead. -It might even boost throughtput in case where the NIC is the bottleneck -because of the extra compression. +To enable the usage of the `CURVE` mechanism, the feature flag 'curve' +must be enabled. However, this time we will use an external configuration file to get rid of all the boilerplate. This will also allows our application to run indepently of the socket configuration. +Based on some basic benchmarks, the `CURVE` mechanism +might reduce the throughtput of I/O heavy applications by half due +to the overhead of the `salsa20` encryption. + ## Config File In this case we used `yaml` configuration file, but any file format diff --git a/libzmq-sys/Cargo.toml b/libzmq-sys/Cargo.toml index c8894e1..4e63866 100644 --- a/libzmq-sys/Cargo.toml +++ b/libzmq-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libzmq-sys" -version = "0.1.6" +version = "0.1.7+4.3.2" authors = ["jean-airoldie "] edition = "2018" license = "MIT OR Apache-2.0" @@ -20,9 +20,11 @@ maintenance = { status = "actively-developed" } [features] # Renew the pre-generated `libzmq` bindings. renew-bindings = ['bindgen'] +libsodium = ['libsodium-sys'] [dependencies] libc = "0.2" +libsodium-sys = { version = "0.2.3", optional = true } [dev-dependencies] version-sync = "0.8" @@ -30,5 +32,5 @@ version-sync = "0.8" [build-dependencies] cmake = "0.1" bindgen = { version = "0.49.0", optional = true } -# Use `libzmq` version 4.3.2 which is still a dev preview. -zeromq-src = "0.1.7" +# libzmq 4.3.2 +zeromq-src = "0.1.8" diff --git a/libzmq-sys/build.rs b/libzmq-sys/build.rs index 595d1c4..f035140 100644 --- a/libzmq-sys/build.rs +++ b/libzmq-sys/build.rs @@ -32,10 +32,22 @@ fn main() { let wants_debug = env::var_os("PROFILE").unwrap() == "debug"; + let maybe_libsodium = if cfg!(feature = "libsodium") { + let lib_dir = env::var("DEP_SODIUM_LIB") + .expect("build metadata `DEP_SODIUM_LIB` required"); + let include_dir = env::var("DEP_SODIUM_INCLUDE") + .expect("build metadata `DEP_SODIUM_INCLUDE` required"); + + Some(zeromq_src::LibLocation::new(lib_dir, include_dir)) + } else { + None + }; + let artifacts = zeromq_src::Build::new() .link_static(true) .enable_draft(true) .build_debug(wants_debug) + .with_libsodium(maybe_libsodium) .build(); artifacts.print_cargo_metadata(); diff --git a/libzmq-sys/src/lib.rs b/libzmq-sys/src/lib.rs index 36f2812..2688c72 100644 --- a/libzmq-sys/src/lib.rs +++ b/libzmq-sys/src/lib.rs @@ -1,6 +1,6 @@ // Ignore generated code #![allow(clippy::all)] -#![doc(html_root_url = "https://docs.rs/libzmq-sys/0.1.6")] +#![doc(html_root_url = "https://docs.rs/libzmq-sys/0.1.7")] //! libzmq-sys - Raw cFFI bindings to [libzmq](https://github.com/zeromq/libzmq). diff --git a/libzmq/Cargo.toml b/libzmq/Cargo.toml index a8c67fa..26019a6 100644 --- a/libzmq/Cargo.toml +++ b/libzmq/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libzmq" -version = "0.1.24" +version = "0.2.0" authors = ["jean-airoldie "] edition = "2018" license = "MIT OR Apache-2.0" @@ -17,6 +17,9 @@ homepage = "https://jean-airoldie.github.io/libzmq-rs/" [badges] maintenance = { status = "actively-developed" } +[features] +curve = ['libzmq-sys/libsodium'] + [dependencies] libc = "0.2" serde = { version = "1.0", features = ["derive"] } @@ -24,9 +27,8 @@ humantime-serde = "0.1" serde_with = "1.3.1" lazy_static = "1.3.0" failure = "0.1" -libzmq-sys = { path = "../libzmq-sys", version = "0.1.6" } +libzmq-sys = { path = "../libzmq-sys", version = "0.1.7" } bitflags = "1.0" -hashbrown = "0.2" log = "0.4" uuid = { version = "0.7", features = ["v4"] } bincode = "1.1" @@ -38,13 +40,17 @@ rand_isaac = "0.1.1" rand_core = "0.4" criterion = "0.2" version-sync = "0.8" -ron = "0.5" quickcheck = "0.8.3" serde_yaml = "0.8" [build-dependencies] flatc-rust = "0.1" +[[example]] +name = "secure_req_rep" +required-features = ['curve'] + [[bench]] +required-features = ['curve'] name = "bench_main" harness = false diff --git a/libzmq/benches/bench_main.rs b/libzmq/benches/bench_main.rs index c1f875b..f9cc0b2 100644 --- a/libzmq/benches/bench_main.rs +++ b/libzmq/benches/bench_main.rs @@ -6,9 +6,9 @@ use criterion::{criterion_group, criterion_main}; use std::time::Duration; -const MSG_AMOUNT: usize = 100_000; -const MSG_SIZE: usize = 50; -const HWM: i32 = 1_000; +const MSG_AMOUNT: usize = 50; +const MSG_SIZE: usize = 500_000; // 0.5MB messages +const HWM: i32 = 10; const SAMPLE_SIZE: usize = 10; const MEASUREMENT_TIME: Duration = Duration::from_secs(30); diff --git a/libzmq/src/auth/client.rs b/libzmq/src/auth/client.rs index bcb6420..3529b58 100644 --- a/libzmq/src/auth/client.rs +++ b/libzmq/src/auth/client.rs @@ -44,42 +44,44 @@ fn into_ipv6(ip: IpAddr) -> Ipv6Addr { /// # use failure::Error; /// # /// # fn main() -> Result<(), Error> { -/// use libzmq::{prelude::*, auth::*, *}; -/// use std::{time::Duration}; +/// #[cfg(feature = "curve")] { +/// use libzmq::{prelude::*, auth::*, *}; +/// use std::{time::Duration}; /// -/// let server_cert = CurveCert::new_unique(); -/// let client_cert = CurveCert::new_unique(); +/// let server_cert = CurveCert::new_unique(); +/// let client_cert = CurveCert::new_unique(); /// -/// let addr: TcpAddr = "127.0.0.1:*".try_into()?; +/// let addr: TcpAddr = "127.0.0.1:*".try_into()?; /// -/// let server_creds = CurveServerCreds::new(server_cert.secret()); +/// let server_creds = CurveServerCreds::new(server_cert.secret()); /// -/// // Creates a server using the `CurveServer` mechanism. Since `CURVE` -/// // authentication is enabled by default, only sockets whose public key -/// // is in the whitelist will be allowed to connect. -/// let server = ServerBuilder::new() -/// .bind(&addr) -/// .mechanism(server_creds) -/// .recv_timeout(Duration::from_millis(200)) -/// .build()?; +/// // Creates a server using the `CurveServer` mechanism. Since `CURVE` +/// // authentication is enabled by default, only sockets whose public key +/// // is in the whitelist will be allowed to connect. +/// let server = ServerBuilder::new() +/// .bind(&addr) +/// .mechanism(server_creds) +/// .recv_timeout(Duration::from_millis(200)) +/// .build()?; /// -/// // We need to tell the `AuthServer` to allow the client's public key. -/// let _ = AuthBuilder::new().curve_registry(client_cert.public()).build()?; +/// // We need to tell the `AuthServer` to allow the client's public key. +/// let _ = AuthBuilder::new().curve_registry(client_cert.public()).build()?; /// -/// let bound = server.last_endpoint()?; +/// let bound = server.last_endpoint()?; /// -/// let client_creds = CurveClientCreds::new(server_cert.public()) -/// .add_cert(client_cert); +/// let client_creds = CurveClientCreds::new(server_cert.public()) +/// .add_cert(client_cert); /// -/// // Creates a server using the `CurveServer` mechanism. Since `CURVE` -/// let client = ClientBuilder::new() -/// .mechanism(client_creds) -/// .connect(bound) -/// .build()?; +/// // Creates a server using the `CurveServer` mechanism. Since `CURVE` +/// let client = ClientBuilder::new() +/// .mechanism(client_creds) +/// .connect(bound) +/// .build()?; /// -/// // The handshake is successfull so we can now send and receive messages. -/// client.send("").unwrap(); -/// server.recv_msg().unwrap(); +/// // The handshake is successfull so we can now send and receive messages. +/// client.send("").unwrap(); +/// server.recv_msg().unwrap(); +/// } /// # /// # Ok(()) /// # } @@ -629,6 +631,7 @@ mod test { } #[test] + #[cfg(feature = "curve")] fn test_curve() { // Create a new context to use a disctinct auth handler. let ctx = Ctx::new(); @@ -671,6 +674,7 @@ mod test { } #[test] + #[cfg(feature = "curve")] fn test_curve_denied() { let addr: TcpAddr = "127.0.0.1:*".try_into().unwrap(); @@ -699,6 +703,7 @@ mod test { } #[test] + #[cfg(feature = "curve")] fn test_curve_no_auth() { // Create a new context to use a disctinct auth handler. let ctx = Ctx::new(); diff --git a/libzmq/src/auth/curve.rs b/libzmq/src/auth/curve.rs index e0244c3..9a11cbd 100644 --- a/libzmq/src/auth/curve.rs +++ b/libzmq/src/auth/curve.rs @@ -1,4 +1,5 @@ // The z85 codec logic is largely based on https://github.com/decafbad/z85 +use super::Mechanism; use crate::prelude::TryFrom; use libzmq_sys as sys; @@ -628,6 +629,124 @@ impl<'a> From<&'a CurveSecretKey> for BinCurveKey { } } +/// Credentials for a `Curve` client. +/// +/// # Example +/// ``` +/// use libzmq::auth::*; +/// +/// let server_cert = CurveCert::new_unique(); +/// let client_cert = CurveCert::new_unique(); +/// +/// let creds = CurveClientCreds::new(server_cert.public()) +/// .add_cert(client_cert); +/// ``` +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CurveClientCreds { + pub(crate) client: Option, + pub(crate) server: CurvePublicKey, +} + +impl CurveClientCreds { + /// Create a new `CurveClientCreds` from server's `CurvePublicKey`. + pub fn new(server: S) -> Self + where + S: Into, + { + Self { + client: None, + server: server.into(), + } + } + + /// Associates a client `CurveCert` with the credentials. + pub fn add_cert(mut self, client: C) -> Self + where + C: Into, + { + self.client = Some(client.into()); + self + } + + /// Returns a reference to the client certificate. + pub fn cert(&self) -> Option<&CurveCert> { + self.client.as_ref() + } + + /// Returns a reference to the server public key. + pub fn server(&self) -> &CurvePublicKey { + &self.server + } +} + +impl<'a> From<&'a CurveClientCreds> for CurveClientCreds { + fn from(creds: &'a CurveClientCreds) -> Self { + creds.to_owned() + } +} + +impl<'a> From<&'a CurveClientCreds> for Mechanism { + fn from(creds: &'a CurveClientCreds) -> Self { + Mechanism::CurveClient(creds.to_owned()) + } +} + +impl From for Mechanism { + fn from(creds: CurveClientCreds) -> Self { + Mechanism::CurveClient(creds) + } +} + +/// Credentials for a `Curve` server. +/// # Example +/// ``` +/// use libzmq::auth::*; +/// +/// let server_cert = CurveCert::new_unique(); +/// +/// let creds = CurveServerCreds::new(server_cert.secret()); +/// ``` +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CurveServerCreds { + /// The server's `CurveSecretKey`. + pub(crate) secret: CurveSecretKey, +} + +impl CurveServerCreds { + /// Create a new `CurveServerCreds` from a server secret `CurveSecretKey`. + pub fn new(secret: S) -> Self + where + S: Into, + { + Self { + secret: secret.into(), + } + } + + /// Returns a reference to the server secret key. + pub fn secret(&self) -> &CurveSecretKey { + &self.secret + } +} + +impl<'a> From<&'a CurveServerCreds> for CurveServerCreds { + fn from(creds: &'a CurveServerCreds) -> Self { + creds.to_owned() + } +} + +impl<'a> From<&'a CurveServerCreds> for Mechanism { + fn from(creds: &'a CurveServerCreds) -> Self { + Mechanism::CurveServer(creds.to_owned()) + } +} + +impl From for Mechanism { + fn from(creds: CurveServerCreds) -> Self { + Mechanism::CurveServer(creds) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/libzmq/src/auth/mod.rs b/libzmq/src/auth/mod.rs index ea5439b..e9b27bb 100644 --- a/libzmq/src/auth/mod.rs +++ b/libzmq/src/auth/mod.rs @@ -12,10 +12,167 @@ pub(crate) mod client; mod curve; -mod mechanism; pub(crate) mod server; pub use client::{AuthBuilder, AuthClient}; pub use curve::*; -pub use mechanism::*; pub use server::{StatusCode, StatusCodeParseError}; + +use super::*; +use crate::prelude::TryFrom; + +use failure::Fail; +use serde::{Deserialize, Serialize}; + +use std::option; + +/// Credentials for a `PLAIN` client. +/// # Example +/// ``` +/// use libzmq::auth::*; +/// +/// let creds = PlainClientCreds::new("user", "pass"); +/// ``` +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct PlainClientCreds { + pub(crate) username: String, + pub(crate) password: String, +} + +impl PlainClientCreds { + /// Create a new `PlainClientCreds` from a username and password. + pub fn new(username: U, password: P) -> Self + where + U: Into, + P: Into, + { + Self { + username: username.into(), + password: password.into(), + } + } + + /// Returns a reference to the username. + pub fn username(&self) -> &str { + &self.username + } + + /// Returns a reference to the password. + pub fn password(&self) -> &str { + &self.password + } +} + +impl<'a> From<&'a PlainClientCreds> for PlainClientCreds { + fn from(creds: &'a PlainClientCreds) -> Self { + creds.to_owned() + } +} + +impl<'a> From<&'a PlainClientCreds> for Mechanism { + fn from(creds: &'a PlainClientCreds) -> Self { + Self::from(creds.to_owned()) + } +} + +impl From for Mechanism { + fn from(creds: PlainClientCreds) -> Self { + Mechanism::PlainClient(creds) + } +} + +impl IntoIterator for PlainClientCreds { + type Item = Self; + type IntoIter = option::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + Some(self).into_iter() + } +} + +impl<'a> IntoIterator for &'a PlainClientCreds { + type Item = Self; + type IntoIter = option::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + Some(self).into_iter() + } +} + +/// A socket's `Mechanism`. +/// +/// The `Mechanism` is used to configure the authentication and encryption +/// strategy to use between two connected sockets. +/// +/// By default the `Null` +/// mechanism is used, meaning there is no attempt authentication nor encryption. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum Mechanism { + /// No encryption or authentication. + /// + /// A socket using the `Null` mechanism connect or accept connections from + /// sockets also using the `Null` mechanism. + Null, + /// Plain text authentication with no encryption. + /// + /// A socket using the `PlainClient` mechanism connects to sockets using + /// the `PlainServer` mechanism. + PlainClient(PlainClientCreds), + /// Plain text authentication with no encryption. + /// + /// A socket using the `PlainServer` mechanism accept connections from + /// sockets using the `PlainClient` mechanism. + PlainServer, + /// Secure authentication and encryption using the `Curve` public-key + /// mechanism. + /// + /// By default authentication is done using a whitelist of public keys. + /// However, authentication can be disabled. + /// + /// A socket using the `CurveClient` mechanism connects to socket using the + /// `CurveServer` mechanism. + CurveClient(CurveClientCreds), + /// Secure authentication and encryption using the `Curve` public-key + /// mechanism. + /// + /// A socket using the `CurveServer` mechanism accepts connections from + /// sockets using the `CurveClient` mechanism. + CurveServer(CurveServerCreds), +} + +impl<'a> From<&'a Mechanism> for Mechanism { + fn from(mechanism: &'a Mechanism) -> Self { + mechanism.to_owned() + } +} + +impl Default for Mechanism { + fn default() -> Self { + Mechanism::Null + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) enum MechanismName { + Null, + Plain, + Curve, +} + +#[derive(Debug, Fail)] +#[fail(display = "unsupported mechanism")] +pub(crate) struct InvalidMechanismName; + +impl<'a> TryFrom<&'a str> for MechanismName { + type Error = InvalidMechanismName; + + fn try_from(s: &'a str) -> Result { + match s { + "NULL" => Ok(MechanismName::Null), + "PLAIN" => Ok(MechanismName::Plain), + "CURVE" => Ok(MechanismName::Curve), + _ => Err(InvalidMechanismName), + } + } +} diff --git a/libzmq/src/auth/server.rs b/libzmq/src/auth/server.rs index 14b4095..1a2be5f 100644 --- a/libzmq/src/auth/server.rs +++ b/libzmq/src/auth/server.rs @@ -2,13 +2,17 @@ use super::{client::*, *}; use crate::{old::*, poll::*, prelude::*, socket::*, *}; use failure::Fail; -use hashbrown::{HashMap, HashSet}; use lazy_static::lazy_static; use log::info; use libc::c_long; -use std::{fmt, net::Ipv6Addr, vec}; +use std::{ + collections::{HashMap, HashSet}, + fmt, + net::Ipv6Addr, + vec, +}; const ZAP_VERSION: &str = "1.0"; lazy_static! { diff --git a/libzmq/src/core/mod.rs b/libzmq/src/core/mod.rs index 36d9fd1..9cf7781 100644 --- a/libzmq/src/core/mod.rs +++ b/libzmq/src/core/mod.rs @@ -458,28 +458,36 @@ pub trait Socket: GetRawSocket { } /// Set the socket's [`Mechanism`]. + /// + /// # Feature Flags + /// + /// Note that `Mechanism::CurveClient` and `Mechanism::CurveServer` require + /// the feature flag "curve" to be enabled, and will panic if used otherwise. + /// /// # Example /// ``` /// # use failure::Error; /// # /// # fn main() -> Result<(), Error> { - /// use libzmq::{prelude::*, Client, auth::*}; + /// #[cfg(feature = "curve")] { + /// use libzmq::{prelude::*, Client, auth::*}; /// - /// let client = Client::new()?; - /// assert_eq!(client.mechanism(), Mechanism::Null); + /// let client = Client::new()?; + /// assert_eq!(client.mechanism(), Mechanism::Null); /// - /// let server_cert = CurveCert::new_unique(); - /// // We do not specify a client certificate, so it - /// // will be automatically generated. - /// let creds = CurveClientCreds::new(server_cert.public()); + /// let server_cert = CurveCert::new_unique(); + /// // We do not specify a client certificate, so it + /// // will be automatically generated. + /// let creds = CurveClientCreds::new(server_cert.public()); /// - /// client.set_mechanism(&creds)?; + /// client.set_mechanism(&creds)?; /// - /// if let Mechanism::CurveClient(creds) = client.mechanism() { - /// assert_eq!(creds.server(), server_cert.public()); - /// assert!(creds.cert().is_some()); - /// } else { - /// unreachable!() + /// if let Mechanism::CurveClient(creds) = client.mechanism() { + /// assert_eq!(creds.server(), server_cert.public()); + /// assert!(creds.cert().is_some()); + /// } else { + /// unreachable!() + /// } /// } /// # /// # Ok(()) diff --git a/libzmq/src/core/raw.rs b/libzmq/src/core/raw.rs index 1fe8ad5..99d118e 100644 --- a/libzmq/src/core/raw.rs +++ b/libzmq/src/core/raw.rs @@ -159,6 +159,12 @@ fn unbind(socket_ptr: *mut c_void, c_string: CString) -> Result<(), Error> { } } +fn assert_curve_enabled() { + if cfg!(not(feature = "curve")) { + panic!("CURVE support requires enabling feature flag 'curve'"); + } +} + /// This socket may or may not be thread safe depending on the `RawSocketType`. /// We prevent that it is always thread-safe and let the wrapping types decide. #[derive(Debug)] @@ -400,6 +406,7 @@ impl RawSocket { &self, key: Option<&BinCurveKey>, ) -> Result<(), Error> { + assert_curve_enabled(); let key = key.map(BinCurveKey::as_bytes); setsockopt_bytes(self.as_mut_ptr(), SocketOption::CurvePublicKey, key) } @@ -408,11 +415,13 @@ impl RawSocket { &self, key: Option<&BinCurveKey>, ) -> Result<(), Error> { + assert_curve_enabled(); let key = key.map(BinCurveKey::as_bytes); setsockopt_bytes(self.as_mut_ptr(), SocketOption::CurveSecretKey, key) } pub(crate) fn set_curve_server(&self, enabled: bool) -> Result<(), Error> { + assert_curve_enabled(); setsockopt_bool(self.as_mut_ptr(), SocketOption::CurveServer, enabled) } @@ -420,6 +429,7 @@ impl RawSocket { &self, key: Option<&BinCurveKey>, ) -> Result<(), Error> { + assert_curve_enabled(); let key = key.map(BinCurveKey::as_bytes); setsockopt_bytes(self.as_mut_ptr(), SocketOption::CurveServerKey, key) } diff --git a/libzmq/src/endpoint.rs b/libzmq/src/endpoint.rs index 06f4d88..0cb918b 100644 --- a/libzmq/src/endpoint.rs +++ b/libzmq/src/endpoint.rs @@ -1388,8 +1388,8 @@ mod test { let addr: $name = $string.try_into().unwrap(); let endpoint: Endpoint = addr.into(); - let ron = ron::ser::to_string(&endpoint).unwrap(); - let de: Endpoint = ron::de::from_str(&ron).unwrap(); + let ron = serde_yaml::to_string(&endpoint).unwrap(); + let de: Endpoint = serde_yaml::from_str(&ron).unwrap(); assert_eq!(endpoint, de); } } diff --git a/libzmq/src/error.rs b/libzmq/src/error.rs index d8cd663..e0372dd 100644 --- a/libzmq/src/error.rs +++ b/libzmq/src/error.rs @@ -106,7 +106,7 @@ impl Fail for Error where T: 'static + Debug + Sync + Send, { - fn cause(&self) -> Option<&Fail> { + fn cause(&self) -> Option<&dyn Fail> { self.inner.cause() } diff --git a/libzmq/src/lib.rs b/libzmq/src/lib.rs index a71c021..9af6f2f 100644 --- a/libzmq/src/lib.rs +++ b/libzmq/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/libzmq/0.1.24")] +#![doc(html_root_url = "https://docs.rs/libzmq/0.2")] //! *libzmq* - A strict subset of ØMQ with a high level API. diff --git a/libzmq/src/poll.rs b/libzmq/src/poll.rs index 6483ab9..41a2f86 100644 --- a/libzmq/src/poll.rs +++ b/libzmq/src/poll.rs @@ -206,7 +206,7 @@ impl<'a> Iterator for Iter<'a> { if let Some(event) = raw { // Skip empty events. if event.events == 0 { - return self.next(); + self.next() } else { let user_data = event.user_data as *mut usize as usize; Some(Event { diff --git a/libzmq/src/socket/client.rs b/libzmq/src/socket/client.rs index 41199a7..d235162 100644 --- a/libzmq/src/socket/client.rs +++ b/libzmq/src/socket/client.rs @@ -361,8 +361,8 @@ mod test { let mut config = ClientConfig::new(); config.set_connect(Some(&addr)); - let ron = ron::ser::to_string(&config).unwrap(); - let de: ClientConfig = ron::de::from_str(&ron).unwrap(); + let ron = serde_yaml::to_string(&config).unwrap(); + let de: ClientConfig = serde_yaml::from_str(&ron).unwrap(); assert_eq!(config, de); } } diff --git a/libzmq/src/socket/dish.rs b/libzmq/src/socket/dish.rs index 4ff01c7..8d91960 100644 --- a/libzmq/src/socket/dish.rs +++ b/libzmq/src/socket/dish.rs @@ -518,8 +518,8 @@ mod test { fn test_ser_de() { let config = DishConfig::new(); - let ron = ron::ser::to_string(&config).unwrap(); - let de: DishConfig = ron::de::from_str(&ron).unwrap(); + let ron = serde_yaml::to_string(&config).unwrap(); + let de: DishConfig = serde_yaml::from_str(&ron).unwrap(); assert_eq!(config, de); } diff --git a/libzmq/src/socket/gather.rs b/libzmq/src/socket/gather.rs index 6e7c1a5..1bd108b 100644 --- a/libzmq/src/socket/gather.rs +++ b/libzmq/src/socket/gather.rs @@ -318,8 +318,8 @@ mod test { fn test_ser_de() { let config = GatherConfig::new(); - let ron = ron::ser::to_string(&config).unwrap(); - let de: GatherConfig = ron::de::from_str(&ron).unwrap(); + let ron = serde_yaml::to_string(&config).unwrap(); + let de: GatherConfig = serde_yaml::from_str(&ron).unwrap(); assert_eq!(config, de); } diff --git a/libzmq/src/socket/radio.rs b/libzmq/src/socket/radio.rs index 0d6809c..26e5877 100644 --- a/libzmq/src/socket/radio.rs +++ b/libzmq/src/socket/radio.rs @@ -378,8 +378,8 @@ mod test { fn test_ser_de() { let config = RadioConfig::new(); - let ron = ron::ser::to_string(&config).unwrap(); - let de: RadioConfig = ron::de::from_str(&ron).unwrap(); + let ron = serde_yaml::to_string(&config).unwrap(); + let de: RadioConfig = serde_yaml::from_str(&ron).unwrap(); assert_eq!(config, de); } } diff --git a/libzmq/src/socket/scatter.rs b/libzmq/src/socket/scatter.rs index 0dd18d0..753ee41 100644 --- a/libzmq/src/socket/scatter.rs +++ b/libzmq/src/socket/scatter.rs @@ -310,8 +310,8 @@ mod test { fn test_ser_de() { let config = ScatterConfig::new(); - let ron = ron::ser::to_string(&config).unwrap(); - let de: ScatterConfig = ron::de::from_str(&ron).unwrap(); + let ron = serde_yaml::to_string(&config).unwrap(); + let de: ScatterConfig = serde_yaml::from_str(&ron).unwrap(); assert_eq!(config, de); } diff --git a/libzmq/src/socket/server.rs b/libzmq/src/socket/server.rs index 8e97e5e..de46bf5 100644 --- a/libzmq/src/socket/server.rs +++ b/libzmq/src/socket/server.rs @@ -398,8 +398,8 @@ mod test { fn test_ser_de() { let config = ServerConfig::new(); - let ron = ron::ser::to_string(&config).unwrap(); - let de: ServerConfig = ron::de::from_str(&ron).unwrap(); + let ron = serde_yaml::to_string(&config).unwrap(); + let de: ServerConfig = serde_yaml::from_str(&ron).unwrap(); assert_eq!(config, de); } }