# HG changeset patch # User Martin Habovstiak # Date 1607009649 -3600 # Node ID f740dadd29485a93d34e00a599ba711b91141bd3 # Parent 4479770c22750dc899f1892f193ffc967a8d1953 Added enable_systemd feature This feature makes systemd support optional, on by default. While it may seem strange that this feature exists, it makes sense for authors of applications who want to make systemd optional. Thanks to this feature the interface stays the same, it just fails to parse `systemd://` addresses with a helpful error message. diff -r 4479770c2275 -r f740dadd2948 Cargo.toml --- a/Cargo.toml Sun Nov 29 14:15:33 2020 +0100 +++ b/Cargo.toml Thu Dec 03 16:34:09 2020 +0100 @@ -7,9 +7,11 @@ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] +default = ["enable_systemd"] serde = ["serde_crate", "serde_str_helpers"] +enable_systemd = [] -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(all(target_os = "linux", feature = "enable_systemd"))'.dependencies] libsystemd = "0.2.1" [dependencies] diff -r 4479770c2275 -r f740dadd2948 README.md --- a/README.md Sun Nov 29 14:15:33 2020 +0100 +++ b/README.md Thu Dec 03 16:34:09 2020 +0100 @@ -44,6 +44,9 @@ ## Features +* `enable_systemd` - on by default, the existence of this feature can allow your users to turn + off systemd support if they don't need it. Note that it's already disabled on non-linux + systems, so you don't need to care about that. * `serde` - implements `serde::Deserialize` for `SocketAddr` * `parse_arg` - implements `parse_arg::ParseArg` for `SocketAddr` * `tokio_0_2` - adds `bind_tokio_0_2` method to `SocketAddr` diff -r 4479770c2275 -r f740dadd2948 src/error.rs --- a/src/error.rs Sun Nov 29 14:15:33 2020 +0100 +++ b/src/error.rs Thu Dec 03 16:34:09 2020 +0100 @@ -19,14 +19,15 @@ pub(crate) enum ParseErrorInner { #[error("failed to parse socket address")] ResolvAddr(#[from] crate::resolv_addr::ResolvAddrError), - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] #[error("invalid character '{c}' in systemd socket name {string} at position {pos}")] InvalidCharacter { string: String, c: char, pos: usize, }, - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] #[error("systemd socket name {string} is {len} characters long which is more than the limit 255")] LongSocketName { string: String, len: usize, }, - #[cfg(not(linux))] - #[error("can't parse {0} because systemd is not supported on this operating system")] + #[cfg(not(all(linux, feature = "enable_systemd")))] + #[cfg_attr(not(linux), error("can't parse {0} because systemd is not supported on this operating system"))] + #[cfg_attr(linux, error("can't parse {0} because systemd support was disabled during build"))] SystemdUnsupported(String), } @@ -65,14 +66,14 @@ BindFailed { addr: std::net::SocketAddr, #[source] error: io::Error, }, #[error("failed to bind {addr}")] BindOrResolvFailed { addr: crate::resolv_addr::ResolvAddr, #[source] error: io::Error, }, - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] #[error("failed to receive descriptors with names")] ReceiveDescriptors(#[source] crate::systemd_sockets::Error), #[error("missing systemd socket {0} - a typo or an attempt to bind twice")] - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] MissingDescriptor(String), #[error("the systemd socket {0} is not an internet socket")] - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] NotInetSocket(String), } diff -r 4479770c2275 -r f740dadd2948 src/lib.rs --- a/src/lib.rs Sun Nov 29 14:15:33 2020 +0100 +++ b/src/lib.rs Thu Dec 03 16:34:09 2020 +0100 @@ -42,6 +42,9 @@ //! //! ## Features //! +//! * `enable_systemd` - on by default, the existence of this feature can allow your users to turn +//! off systemd support if they don't need it. Note that it's already disabled on non-linux +//! systems, so you don't need to care about that. //! * `serde` - implements `serde::Deserialize` for `SocketAddr` //! * `parse_arg` - implements `parse_arg::ParseArg` for `SocketAddr` //! * `tokio_0_2` - adds `bind_tokio_0_2` method to `SocketAddr` @@ -65,10 +68,10 @@ use crate::error::*; use crate::resolv_addr::ResolvAddr; -#[cfg(not(linux))] +#[cfg(not(all(linux, feature = "enable_systemd")))] use std::convert::Infallible as Never; -#[cfg(linux)] +#[cfg(all(linux, feature = "enable_systemd"))] pub(crate) mod systemd_sockets { use std::fmt; use std::sync::Mutex; @@ -224,7 +227,7 @@ // rules. fn try_from_generic<'a, T>(string: T) -> Result where T: 'a + std::ops::Deref + Into { if string.starts_with(SYSTEMD_PREFIX) { - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] { let name_len = string.len() - SYSTEMD_PREFIX.len(); match string[SYSTEMD_PREFIX.len()..].chars().enumerate().find(|(_, c)| !c.is_ascii() || *c < ' ' || *c == ':') { @@ -233,7 +236,7 @@ Some((pos, c)) => Err(ParseErrorInner::InvalidCharacter { string: string.into(), c, pos, }.into()), } } - #[cfg(not(linux))] + #[cfg(not(all(linux, feature = "enable_systemd")))] { Err(ParseErrorInner::SystemdUnsupported(string.into()).into()) } @@ -245,7 +248,7 @@ } } - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] fn get_systemd(socket_name: String) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> { use libsystemd::activation::IsType; use std::os::unix::io::{FromRawFd, IntoRawFd}; @@ -265,7 +268,7 @@ } // This approach makes the rest of the code much simpler as it doesn't require sprinkling it - // with #[cfg(linux)] yet still statically guarantees it won't execute. + // with #[cfg(all(linux, feature = "enable_systemd"))] yet still statically guarantees it won't execute. #[cfg(not(linux))] fn get_systemd(socket_name: Never) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> { match socket_name {} @@ -297,9 +300,9 @@ enum SocketAddrInner { Ordinary(std::net::SocketAddr), WithHostname(resolv_addr::ResolvAddr), - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] Systemd(String), - #[cfg(not(linux))] + #[cfg(not(all(linux, feature = "enable_systemd")))] #[allow(dead_code)] Systemd(Never), } @@ -401,13 +404,13 @@ } #[test] - #[cfg(linux)] + #[cfg(all(linux, feature = "enable_systemd"))] fn parse_systemd() { assert_eq!("systemd://foo".parse::().unwrap().0, SocketAddrInner::Systemd("systemd://foo".to_owned())); } #[test] - #[cfg(not(linux))] + #[cfg(not(all(linux, feature = "enable_systemd")))] #[should_panic] fn parse_systemd() { "systemd://foo".parse::().unwrap(); diff -r 4479770c2275 -r f740dadd2948 tests/systemd.rs --- a/tests/systemd.rs Sun Nov 29 14:15:33 2020 +0100 +++ b/tests/systemd.rs Thu Dec 03 16:34:09 2020 +0100 @@ -23,7 +23,7 @@ } #[test] -#[cfg_attr(not(linux), should_panic)] +#[cfg_attr(not(all(linux, feature = "enable_systemd")), should_panic)] fn main() { comm::main::(); }