annotate src/lib.rs @ 22:f33e2c048104

Enable `doc_auto_cfg` in docs.rs builds
author Martin Habovstiak <martin.habovstiak@gmail.com>
date Sat, 13 Jul 2024 15:13:21 +0200
parents f6334887e3c8
children 1941e9d9819c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
1 //! A convenience crate for optionally supporting systemd socket activation.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
2 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
3 //! ## About
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
4 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
5 //! The goal of this crate is to make socket activation with systemd in your project trivial.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
6 //! It provides a replacement for `std::net::SocketAddr` that allows parsing the bind address from string just like the one from `std`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
7 //! but on top of that also allows `systemd://socket_name` format that tells it to use systemd activation with given socket name.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
8 //! Then it provides a method to bind the address which will return the socket from systemd if available.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
9 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
10 //! The provided type supports conversions from various types of strings and also `serde` and `parse_arg` via feature flag.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
11 //! Thanks to this the change to your code should be minimal - parsing will continue to work, it'll just allow a new format.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
12 //! You only need to change the code to use `SocketAddr::bind()` instead of `TcpListener::bind()` for binding.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
13 //!
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
14 //! You also don't need to worry about conditional compilation to ensure OS compatibility.
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
15 //! This crate handles that for you by disabling systemd on non-linux systems.
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
16 //!
21
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
17 //! Further, the crate also provides methods for binding `tokio` 1.0, 0.2, 0.3, and `async_std` sockets if the appropriate features are
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
18 //! activated.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
19 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
20 //! ## Example
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
21 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
22 //! ```no_run
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
23 //! use systemd_socket::SocketAddr;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
24 //! use std::convert::TryFrom;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
25 //! use std::io::Write;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
26 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
27 //! let mut args = std::env::args_os();
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
28 //! let program_name = args.next().expect("unknown program name");
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
29 //! let socket_addr = args.next().expect("missing socket address");
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
30 //! let socket_addr = SocketAddr::try_from(socket_addr).expect("failed to parse socket address");
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
31 //! let socket = socket_addr.bind().expect("failed to bind socket");
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
32 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
33 //! loop {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
34 //! let _ = socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
35 //! .accept()
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
36 //! .expect("failed to accept connection")
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
37 //! .0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
38 //! .write_all(b"Hello world!")
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
39 //! .map_err(|err| eprintln!("Failed to send {}", err));
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
40 //! }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
41 //! ```
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
42 //!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
43 //! ## Features
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
44 //!
13
f740dadd2948 Added enable_systemd feature
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 11
diff changeset
45 //! * `enable_systemd` - on by default, the existence of this feature can allow your users to turn
f740dadd2948 Added enable_systemd feature
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 11
diff changeset
46 //! off systemd support if they don't need it. Note that it's already disabled on non-linux
f740dadd2948 Added enable_systemd feature
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 11
diff changeset
47 //! systems, so you don't need to care about that.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
48 //! * `serde` - implements `serde::Deserialize` for `SocketAddr`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
49 //! * `parse_arg` - implements `parse_arg::ParseArg` for `SocketAddr`
21
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
50 //! * `tokio` - adds `bind_tokio` method to `SocketAddr` (tokio 1.0)
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
51 //! * `tokio_0_2` - adds `bind_tokio_0_2` method to `SocketAddr`
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
52 //! * `tokio_0_3` - adds `bind_tokio_0_3` method to `SocketAddr`
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
53 //! * `async_std` - adds `bind_async_std` method to `SocketAddr`
3
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
54 //!
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
55 //! ## MSRV
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
56 //!
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
57 //! This crate must always compile with the latest Rust available in the latest Debian stable.
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
58 //! That is currently Rust 1.41.1. (Debian 10 - Buster)
0edcde404b02 Added information about MSRV
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 2
diff changeset
59
22
f33e2c048104 Enable `doc_auto_cfg` in docs.rs builds
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 21
diff changeset
60 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
61
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
62 #![deny(missing_docs)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
63
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
64 pub mod error;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
65 mod resolv_addr;
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
66
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
67 use std::convert::{TryFrom, TryInto};
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
68 use std::fmt;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
69 use std::ffi::{OsStr, OsString};
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
70 use crate::error::*;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
71 use crate::resolv_addr::ResolvAddr;
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
72
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
73 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
74 use std::convert::Infallible as Never;
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
75
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
76 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
77 pub(crate) mod systemd_sockets {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
78 use std::fmt;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
79 use std::sync::Mutex;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
80 use libsystemd::activation::FileDescriptor;
20
2b78a483f84b Update `libsystemd`
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 18
diff changeset
81 use libsystemd::errors::SdError as LibSystemdError;
2b78a483f84b Update `libsystemd`
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 18
diff changeset
82 type LibSystemdResult<T> = Result<T, LibSystemdError>;
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
83
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
84 #[derive(Debug)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
85 pub(crate) struct Error(&'static Mutex<LibSystemdError>);
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
86
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
87 impl fmt::Display for Error {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
88 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
89 fmt::Display::fmt(&*self.0.lock().expect("mutex poisoned"), f)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
90 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
91 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
92
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
93 // No source we can't keep the mutex locked
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
94 impl std::error::Error for Error {}
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
95
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
96 pub(crate) fn take(name: &str) -> Result<Option<FileDescriptor>, Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
97 match &*SYSTEMD_SOCKETS {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
98 Ok(sockets) => Ok(sockets.take(name)),
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
99 Err(error) => Err(Error(error))
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
100 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
101 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
102
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
103 struct SystemdSockets(std::sync::Mutex<std::collections::HashMap<String, FileDescriptor>>);
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
104
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
105 impl SystemdSockets {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
106 fn new() -> LibSystemdResult<Self> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
107 // MUST BE true FOR SAFETY!!!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
108 let map = libsystemd::activation::receive_descriptors_with_names(/*unset env = */ true)?.into_iter().map(|(fd, name)| (name, fd)).collect();
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
109 Ok(SystemdSockets(Mutex::new(map)))
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
110 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
111
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
112 fn take(&self, name: &str) -> Option<FileDescriptor> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
113 // MUST remove THE SOCKET FOR SAFETY!!!
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
114 self.0.lock().expect("poisoned mutex").remove(name)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
115 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
116 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
117
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
118 lazy_static::lazy_static! {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
119 // We don't panic in order to let the application handle the error later
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
120 static ref SYSTEMD_SOCKETS: Result<SystemdSockets, Mutex<LibSystemdError>> = SystemdSockets::new().map_err(Mutex::new);
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
121 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
122 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
123
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
124 /// Socket address that can be an ordinary address or a systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
125 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
126 /// This is the core type of this crate that abstracts possible addresses.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
127 /// It can be (fallibly) converted from various types of strings or deserialized with `serde`.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
128 /// After it's created, it can be bound as `TcpListener` from `std` or even `tokio` or `async_std`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
129 /// if the appropriate feature is enabled.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
130 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
131 /// Optional dependencies on `parse_arg` and `serde` make it trivial to use with
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
132 /// [`configure_me`](https://crates.io/crates/configure_me).
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
133 #[derive(Debug)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
134 #[cfg_attr(feature = "serde", derive(serde_crate::Deserialize), serde(crate = "serde_crate", try_from = "serde_str_helpers::DeserBorrowStr"))]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
135 pub struct SocketAddr(SocketAddrInner);
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
136
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
137 impl SocketAddr {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
138 /// Creates SocketAddr from systemd name directly, without requiring `systemd://` prefix.
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
139 ///
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
140 /// Always fails with systemd unsupported error if systemd is not supported.
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
141 pub fn from_systemd_name<T: Into<String>>(name: T) -> Result<Self, ParseError> {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
142 Self::inner_from_systemd_name(name.into(), false)
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
143 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
144
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
145 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
146 fn inner_from_systemd_name(name: String, prefixed: bool) -> Result<Self, ParseError> {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
147 let real_systemd_name = if prefixed {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
148 &name[SYSTEMD_PREFIX.len()..]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
149 } else {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
150 &name
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
151 };
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
152
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
153 let name_len = real_systemd_name.len();
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
154 match real_systemd_name.chars().enumerate().find(|(_, c)| !c.is_ascii() || *c < ' ' || *c == ':') {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
155 None if name_len <= 255 && prefixed => Ok(SocketAddr(SocketAddrInner::Systemd(name))),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
156 None if name_len <= 255 && !prefixed => Ok(SocketAddr(SocketAddrInner::SystemdNoPrefix(name))),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
157 None => Err(ParseErrorInner::LongSocketName { string: name, len: name_len }.into()),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
158 Some((pos, c)) => Err(ParseErrorInner::InvalidCharacter { string: name, c, pos, }.into()),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
159 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
160 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
161
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
162
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
163 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
164 fn inner_from_systemd_name(name: String, _prefixed: bool) -> Result<Self, ParseError> {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
165 Err(ParseError(ParseErrorInner::SystemdUnsupported(name)))
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
166 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
167
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
168 /// Creates `std::net::TcpListener`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
169 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
170 /// This method either `binds` the socket, if the address was provided or uses systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
171 /// if the socket name was provided.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
172 pub fn bind(self) -> Result<std::net::TcpListener, BindError> {
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
173 match self.0 {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
174 SocketAddrInner::Ordinary(addr) => match std::net::TcpListener::bind(addr) {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
175 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
176 Err(error) => Err(BindErrorInner::BindFailed { addr, error, }.into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
177 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
178 SocketAddrInner::WithHostname(addr) => match std::net::TcpListener::bind(addr.as_str()) {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
179 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
180 Err(error) => Err(BindErrorInner::BindOrResolvFailed { addr, error, }.into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
181 },
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
182 SocketAddrInner::Systemd(socket_name) => Self::get_systemd(socket_name, true).map(|(socket, _)| socket),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
183 SocketAddrInner::SystemdNoPrefix(socket_name) => Self::get_systemd(socket_name, false).map(|(socket, _)| socket),
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
184 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
185 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
186
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
187 /// Creates `tokio::net::TcpListener`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
188 ///
21
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
189 /// To be specific, it binds the socket or converts systemd socket to `tokio` 1.0 socket.
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
190 ///
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
191 /// This method either `binds` the socket, if the address was provided or uses systemd socket
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
192 /// if the socket name was provided.
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
193 #[cfg(feature = "tokio")]
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
194 pub async fn bind_tokio(self) -> Result<tokio::net::TcpListener, TokioBindError> {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
195 match self.0 {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
196 SocketAddrInner::Ordinary(addr) => match tokio::net::TcpListener::bind(addr).await {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
197 Ok(socket) => Ok(socket),
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
198 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindFailed { addr, error, }.into())),
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
199 },
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
200 SocketAddrInner::WithHostname(addr) => match tokio::net::TcpListener::bind(addr.as_str()).await {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
201 Ok(socket) => Ok(socket),
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
202 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindOrResolvFailed { addr, error, }.into())),
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
203 },
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
204 SocketAddrInner::Systemd(socket_name) => {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
205 let (socket, addr) = Self::get_systemd(socket_name, true)?;
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
206 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
207 },
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
208 SocketAddrInner::SystemdNoPrefix(socket_name) => {
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
209 let (socket, addr) = Self::get_systemd(socket_name, false)?;
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
210 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
211 },
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
212 }
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
213 }
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
214
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
215 /// Creates `tokio::net::TcpListener`
f6334887e3c8 Support `tokio` 1.0
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 20
diff changeset
216 ///
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
217 /// To be specific, it binds the socket or converts systemd socket to `tokio` 0.2 socket.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
218 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
219 /// This method either `binds` the socket, if the address was provided or uses systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
220 /// if the socket name was provided.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
221 #[cfg(feature = "tokio_0_2")]
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
222 pub async fn bind_tokio_0_2(self) -> Result<tokio_0_2::net::TcpListener, TokioBindError> {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
223 match self.0 {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
224 SocketAddrInner::Ordinary(addr) => match tokio_0_2::net::TcpListener::bind(addr).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
225 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
226 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindFailed { addr, error, }.into())),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
227 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
228 SocketAddrInner::WithHostname(addr) => match tokio_0_2::net::TcpListener::bind(addr.as_str()).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
229 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
230 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindOrResolvFailed { addr, error, }.into())),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
231 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
232 SocketAddrInner::Systemd(socket_name) => {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
233 let (socket, addr) = Self::get_systemd(socket_name, true)?;
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
234 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
235 },
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
236 SocketAddrInner::SystemdNoPrefix(socket_name) => {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
237 let (socket, addr) = Self::get_systemd(socket_name, false)?;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
238 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
239 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
240 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
241 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
242
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
243 /// Creates `tokio::net::TcpListener`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
244 ///
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
245 /// To be specific, it binds the socket or converts systemd socket to `tokio` 0.3 socket.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
246 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
247 /// This method either `binds` the socket, if the address was provided or uses systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
248 /// if the socket name was provided.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
249 #[cfg(feature = "tokio_0_3")]
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
250 pub async fn bind_tokio_0_3(self) -> Result<tokio_0_3::net::TcpListener, TokioBindError> {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
251 match self.0 {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
252 SocketAddrInner::Ordinary(addr) => match tokio_0_3::net::TcpListener::bind(addr).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
253 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
254 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindFailed { addr, error, }.into())),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
255 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
256 SocketAddrInner::WithHostname(addr) => match tokio_0_3::net::TcpListener::bind(addr.as_str()).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
257 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
258 Err(error) => Err(TokioBindError::Bind(BindErrorInner::BindOrResolvFailed { addr, error, }.into())),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
259 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
260 SocketAddrInner::Systemd(socket_name) => {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
261 let (socket, addr) = Self::get_systemd(socket_name, true)?;
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
262 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
263 },
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
264 SocketAddrInner::SystemdNoPrefix(socket_name) => {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
265 let (socket, addr) = Self::get_systemd(socket_name, false)?;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
266 socket.try_into().map_err(|error| TokioConversionError { addr, error, }.into())
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
267 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
268 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
269 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
270
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
271 /// Creates `async_std::net::TcpListener`
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
272 ///
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
273 /// To be specific, it binds the socket or converts systemd socket to `async_std` socket.
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
274 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
275 /// This method either `binds` the socket, if the address was provided or uses systemd socket
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
276 /// if the socket name was provided.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
277 #[cfg(feature = "async-std")]
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
278 pub async fn bind_async_std(self) -> Result<async_std::net::TcpListener, BindError> {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
279 match self.0 {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
280 SocketAddrInner::Ordinary(addr) => match async_std::net::TcpListener::bind(addr).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
281 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
282 Err(error) => Err(BindErrorInner::BindFailed { addr, error, }.into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
283 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
284 SocketAddrInner::WithHostname(addr) => match async_std::net::TcpListener::bind(addr.as_str()).await {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
285 Ok(socket) => Ok(socket),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
286 Err(error) => Err(BindErrorInner::BindOrResolvFailed { addr, error, }.into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
287 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
288 SocketAddrInner::Systemd(socket_name) => {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
289 let (socket, _) = Self::get_systemd(socket_name, true)?;
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
290 Ok(socket.into())
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
291 },
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
292 SocketAddrInner::SystemdNoPrefix(socket_name) => {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
293 let (socket, _) = Self::get_systemd(socket_name, false)?;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
294 Ok(socket.into())
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
295 },
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
296 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
297 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
298
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
299 // We can't impl<T: Deref<Target=str> + Into<String>> TryFrom<T> for SocketAddr because of orphan
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
300 // rules.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
301 fn try_from_generic<'a, T>(string: T) -> Result<Self, ParseError> where T: 'a + std::ops::Deref<Target=str> + Into<String> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
302 if string.starts_with(SYSTEMD_PREFIX) {
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
303 Self::inner_from_systemd_name(string.into(), true)
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
304 } else {
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
305 match string.parse() {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
306 Ok(addr) => Ok(SocketAddr(SocketAddrInner::Ordinary(addr))),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
307 Err(_) => Ok(SocketAddr(SocketAddrInner::WithHostname(ResolvAddr::try_from_generic(string).map_err(ParseErrorInner::ResolvAddr)?))),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
308 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
309 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
310 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
311
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
312 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
313 fn get_systemd(socket_name: String, prefixed: bool) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> {
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
314 use libsystemd::activation::IsType;
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
315 use std::os::unix::io::{FromRawFd, IntoRawFd};
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
316
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
317 let real_systemd_name = if prefixed {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
318 &socket_name[SYSTEMD_PREFIX.len()..]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
319 } else {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
320 &socket_name
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
321 };
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
322
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
323 let socket = systemd_sockets::take(real_systemd_name).map_err(BindErrorInner::ReceiveDescriptors)?;
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
324 // Safety: The environment variable is unset, so that no other calls can get the
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
325 // descriptors. The descriptors are taken from the map, not cloned, so they can't
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
326 // be duplicated.
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
327 unsafe {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
328 // match instead of combinators to avoid cloning socket_name
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
329 match socket {
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
330 Some(socket) if socket.is_inet() => Ok((std::net::TcpListener::from_raw_fd(socket.into_raw_fd()), SocketAddrInner::Systemd(socket_name))),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
331 Some(_) => Err(BindErrorInner::NotInetSocket(socket_name).into()),
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
332 None => Err(BindErrorInner::MissingDescriptor(socket_name).into())
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
333 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
334 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
335 }
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
336
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
337 // This approach makes the rest of the code much simpler as it doesn't require sprinkling it
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
338 // with #[cfg(all(target_os = "linux", feature = "enable_systemd"))] yet still statically guarantees it won't execute.
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
339 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
340 fn get_systemd(socket_name: Never, _prefixed: bool) -> Result<(std::net::TcpListener, SocketAddrInner), BindError> {
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
341 match socket_name {}
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
342 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
343 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
344
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
345 /// Displays the address in format that can be parsed again.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
346 ///
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
347 /// **Important: While I don't expect this impl to change, don't rely on it!**
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
348 /// It should be used mostly for debugging/logging.
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
349 impl fmt::Display for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
350 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
351 fmt::Display::fmt(&self.0, f)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
352 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
353 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
354
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
355 impl fmt::Display for SocketAddrInner {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
356 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
357 match self {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
358 SocketAddrInner::Ordinary(addr) => fmt::Display::fmt(addr, f),
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
359 SocketAddrInner::Systemd(addr) => fmt::Display::fmt(addr, f),
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
360 SocketAddrInner::SystemdNoPrefix(addr) => write!(f, "{}{}", SYSTEMD_PREFIX, addr),
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
361 SocketAddrInner::WithHostname(addr) => fmt::Display::fmt(addr, f),
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
362 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
363 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
364 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
365
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
366 // PartialEq for testing, I'm not convinced it should be exposed
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
367 #[derive(Debug, PartialEq)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
368 enum SocketAddrInner {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
369 Ordinary(std::net::SocketAddr),
4
66c0e10c89fc Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 3
diff changeset
370 WithHostname(resolv_addr::ResolvAddr),
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
371 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
372 Systemd(String),
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
373 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
6
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
374 #[allow(dead_code)]
a7893294e9b2 Make the crate compilable on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 4
diff changeset
375 Systemd(Never),
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
376 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
377 #[allow(dead_code)]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
378 SystemdNoPrefix(String),
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
379 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
380 #[allow(dead_code)]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
381 SystemdNoPrefix(Never),
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
382 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
383
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
384 const SYSTEMD_PREFIX: &str = "systemd://";
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
385
11
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
386 impl<I: Into<std::net::IpAddr>> From<(I, u16)> for SocketAddr {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
387 fn from(value: (I, u16)) -> Self {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
388 SocketAddr(SocketAddrInner::Ordinary(value.into()))
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
389 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
390 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
391
18
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
392 impl From<std::net::SocketAddr> for SocketAddr {
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
393 fn from(value: std::net::SocketAddr) -> Self {
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
394 SocketAddr(SocketAddrInner::Ordinary(value))
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
395 }
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
396 }
db1dc99252e2 Added From<std::net::SocketAddr>
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 17
diff changeset
397
11
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
398 impl From<std::net::SocketAddrV4> for SocketAddr {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
399 fn from(value: std::net::SocketAddrV4) -> Self {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
400 SocketAddr(SocketAddrInner::Ordinary(value.into()))
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
401 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
402 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
403
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
404 impl From<std::net::SocketAddrV6> for SocketAddr {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
405 fn from(value: std::net::SocketAddrV6) -> Self {
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
406 SocketAddr(SocketAddrInner::Ordinary(value.into()))
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
407 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
408 }
13e2a5545167 Implement From conversions
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 9
diff changeset
409
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
410 impl std::str::FromStr for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
411 type Err = ParseError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
412
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
413 fn from_str(s: &str) -> Result<Self, Self::Err> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
414 SocketAddr::try_from_generic(s)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
415 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
416 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
417
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
418 impl<'a> TryFrom<&'a str> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
419 type Error = ParseError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
420
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
421 fn try_from(s: &'a str) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
422 SocketAddr::try_from_generic(s)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
423 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
424 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
425
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
426 impl TryFrom<String> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
427 type Error = ParseError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
428
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
429 fn try_from(s: String) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
430 SocketAddr::try_from_generic(s)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
431 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
432 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
433
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
434 impl<'a> TryFrom<&'a OsStr> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
435 type Error = ParseOsStrError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
436
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
437 fn try_from(s: &'a OsStr) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
438 s.to_str().ok_or(ParseOsStrError::InvalidUtf8)?.try_into().map_err(Into::into)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
439 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
440 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
441
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
442 impl TryFrom<OsString> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
443 type Error = ParseOsStrError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
444
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
445 fn try_from(s: OsString) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
446 s.into_string().map_err(|_| ParseOsStrError::InvalidUtf8)?.try_into().map_err(Into::into)
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
447 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
448 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
449
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
450 #[cfg(feature = "serde")]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
451 impl<'a> TryFrom<serde_str_helpers::DeserBorrowStr<'a>> for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
452 type Error = ParseError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
453
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
454 fn try_from(s: serde_str_helpers::DeserBorrowStr<'a>) -> Result<Self, Self::Error> {
9
4fb70ca820a6 Upgrade serde_str_helpers
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 7
diff changeset
455 SocketAddr::try_from_generic(s)
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
456 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
457 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
458
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
459 #[cfg(feature = "parse_arg")]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
460 impl parse_arg::ParseArg for SocketAddr {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
461 type Error = ParseOsStrError;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
462
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
463 fn describe_type<W: fmt::Write>(mut writer: W) -> fmt::Result {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
464 std::net::SocketAddr::describe_type(&mut writer)?;
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
465 write!(writer, " or a systemd socket name prefixed with systemd://")
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
466 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
467
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
468 fn parse_arg(arg: &OsStr) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
469 arg.try_into()
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
470 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
471
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
472 fn parse_owned_arg(arg: OsString) -> Result<Self, Self::Error> {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
473 arg.try_into()
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
474 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
475 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
476
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
477 #[cfg(test)]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
478 mod tests {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
479 use super::{SocketAddr, SocketAddrInner};
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
480
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
481 #[test]
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
482 fn parse_ordinary() {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
483 assert_eq!("127.0.0.1:42".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Ordinary(([127, 0, 0, 1], 42).into()));
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
484 }
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
485
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
486 #[test]
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
487 #[cfg(all(target_os = "linux", feature = "enable_systemd"))]
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
488 fn parse_systemd() {
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
489 assert_eq!("systemd://foo".parse::<SocketAddr>().unwrap().0, SocketAddrInner::Systemd("systemd://foo".to_owned()));
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
490 }
2
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
491
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
492 #[test]
16
bc76507dd878 Fixed conditional compilation based on OS
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 13
diff changeset
493 #[cfg(not(all(target_os = "linux", feature = "enable_systemd")))]
7
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
494 #[should_panic]
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
495 fn parse_systemd() {
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
496 "systemd://foo".parse::<SocketAddr>().unwrap();
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
497 }
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
498
9731ff589d9c Fix tests on non-linux systems
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 6
diff changeset
499 #[test]
2
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
500 #[should_panic]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
501 fn parse_systemd_fail_control() {
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
502 "systemd://foo\n".parse::<SocketAddr>().unwrap();
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
503 }
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
504
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
505 #[test]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
506 #[should_panic]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
507 fn parse_systemd_fail_colon() {
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
508 "systemd://foo:".parse::<SocketAddr>().unwrap();
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
509 }
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
510
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
511 #[test]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
512 #[should_panic]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
513 fn parse_systemd_fail_non_ascii() {
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
514 "systemd://fooá".parse::<SocketAddr>().unwrap();
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
515 }
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
516
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
517 #[test]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
518 #[should_panic]
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
519 fn parse_systemd_fail_too_long() {
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
520 "systemd://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".parse::<SocketAddr>().unwrap();
cabc4aafdd85 Added length check and a few tests
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 0
diff changeset
521 }
17
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
522
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
523 #[test]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
524 #[cfg_attr(not(all(target_os = "linux", feature = "enable_systemd")), should_panic)]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
525 fn no_prefix_parse_systemd() {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
526 SocketAddr::from_systemd_name("foo").unwrap();
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
527 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
528
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
529 #[test]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
530 #[should_panic]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
531 fn no_prefix_parse_systemd_fail_non_ascii() {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
532 SocketAddr::from_systemd_name("fooá").unwrap();
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
533 }
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
534
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
535 #[test]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
536 #[should_panic]
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
537 fn no_prefix_parse_systemd_fail_too_long() {
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
538 SocketAddr::from_systemd_name("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").unwrap();
dfb727367934 Allow specifying systemd name directly
Martin Habovstiak <martin.habovstiak@gmail.com>
parents: 16
diff changeset
539 }
0
a65053246c29 Initial commit
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff changeset
540 }