use futures_lite::{AsyncRead, AsyncWrite};
use std::{future::Future, io::Result as IoResult, net::SocketAddr};
#[allow(unused_macros)]
macro_rules! connector_ctor {
(non_tls: $(#[$meta:meta])*) => {
#[doc = "Create a new"]
$(#[$meta])*
#[doc = "non-TLS connector that connects to the ***default Twitch*** address."]
pub fn twitch() -> ::std::io::Result<Self> {
Self::custom($crate::TWITCH_IRC_ADDRESS)
}
#[doc = "Create a new"]
$(#[$meta])*
#[doc = "non-TLS connector with a custom address."]
pub fn custom<A>(addrs: A) -> ::std::io::Result<Self>
where
A: ::std::net::ToSocketAddrs,
{
addrs.to_socket_addrs().map(|addrs| Self {
addrs: addrs.collect(),
})
}
};
(tls: $(#[$meta:meta])*) => {
#[doc = "Create a new"]
$(#[$meta])*
#[doc = "TLS connector that connects to the ***default Twitch*** address."]
pub fn twitch() -> ::std::io::Result<Self> {
Self::custom($crate::TWITCH_IRC_ADDRESS_TLS, $crate::TWITCH_TLS_DOMAIN)
}
#[doc = "Create a new"]
$(#[$meta])*
#[doc = "TLS connector with a custom address and TLS domain."]
pub fn custom<A, D>(addrs: A, domain: D) -> ::std::io::Result<Self>
where
A: ::std::net::ToSocketAddrs,
D: Into<::std::string::String>,
{
let tls_domain = domain.into();
addrs.to_socket_addrs().map(|addrs| Self {
addrs: addrs.collect(),
tls_domain,
})
}
};
}
#[cfg(feature = "async-io")]
pub mod async_io;
#[cfg(feature = "async-io")]
#[doc(inline)]
pub use self::async_io::Connector as AsyncIoConnector;
#[cfg(all(feature = "async-io", feature = "async-tls"))]
#[doc(inline)]
pub use self::async_io::ConnectorTls as AsyncIoConnectorTls;
#[cfg(feature = "async-std")]
pub mod async_std;
#[cfg(feature = "async-std")]
#[doc(inline)]
pub use self::async_std::Connector as AsyncStdConnector;
#[cfg(all(feature = "async-std", feature = "async-tls"))]
#[doc(inline)]
pub use self::async_std::ConnectorTls as AsyncStdConnectorTls;
#[cfg(feature = "smol")]
pub mod smol;
#[cfg(feature = "smol")]
#[doc(inline)]
pub use self::smol::Connector as SmolConnector;
#[cfg(all(feature = "smol", feature = "async-tls"))]
#[doc(inline)]
pub use self::smol::ConnectorTls as SmolConnectorTls;
#[cfg(all(feature = "tokio", feature = "tokio-util"))]
pub mod tokio;
#[cfg(all(feature = "tokio", feature = "tokio-util"))]
#[doc(inline)]
pub use self::tokio::Connector as TokioConnector;
#[cfg(all(
feature = "tokio",
feature = "tokio-util",
feature = "tokio-rustls",
feature = "webpki-roots"
))]
#[doc(inline)]
pub use self::tokio::ConnectorRustTls as TokioConnectorRustTls;
#[cfg(all(
feature = "tokio",
feature = "tokio-util",
feature = "tokio-native-tls",
feature = "native-tls"
))]
#[doc(inline)]
pub use self::tokio::ConnectorNativeTls as TokioConnectorNativeTls;
#[cfg(all(
feature = "tokio",
feature = "tokio-util",
feature = "tokio-openssl",
feature = "openssl"
))]
#[doc(inline)]
pub use self::tokio::ConnectorOpenSsl as TokioConnectorOpenSsl;
pub trait Connector: Send + Sync + Clone {
type Output: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static;
fn connect(&mut self) -> crate::BoxedFuture<IoResult<Self::Output>>;
}
#[allow(dead_code)]
async fn try_connect<F, T, R>(addrs: &[SocketAddr], connect: F) -> IoResult<T>
where
F: Fn(SocketAddr) -> R + Send,
R: Future<Output = IoResult<T>> + Send,
T: Send,
{
let mut last = None;
for addr in addrs {
let fut = connect(*addr);
match fut.await {
Ok(socket) => return Ok(socket),
Err(err) => last.replace(err),
};
}
match last {
Some(last) => Err(last),
None => Err(std::io::Error::new(
std::io::ErrorKind::ConnectionRefused,
"cannot connect with any provided address",
)),
}
}
mod required {
#[cfg(all(
feature = "async-tls",
not(any(feature = "async-io", feature = "async-std", feature = "smol"))
))]
compile_error! {
"'async-io' or 'async-std' or 'smol' must be enabled when 'async-tls' is enabled"
}
#[cfg(all(feature = "tokio", not(feature = "tokio-util")))]
compile_error! {
"'tokio-util' must be enabled when 'tokio' is enabled"
}
#[cfg(all(
feature = "tokio-native-tls",
not(all(feature = "tokio", feature = "tokio-util", feature = "native-tls"))
))]
compile_error! {
"'tokio', 'tokio-util' and 'native-tls' must be enabled when 'tokio-native-tls' is enabled"
}
#[cfg(all(
feature = "tokio-rustls",
not(all(feature = "tokio", feature = "tokio-util", feature = "webpki-roots"))
))]
compile_error! {
"'tokio', 'tokio-util' and 'webpki-roots' must be enabled when 'tokio-rustls' is enabled"
}
#[cfg(all(
feature = "tokio-openssl",
not(all(feature = "tokio", feature = "tokio-util", feature = "openssl"))
))]
compile_error! {
"'tokio', 'tokio-util' and 'openssl' must be enabled when 'tokio-openssl' is enabled"
}
}
#[cfg(test)]
#[allow(dead_code)]
mod testing {
use crate::connector::Connector as ConnectorTrait;
use futures_lite::{AsyncRead, AsyncWrite};
pub fn assert_connector<T: ConnectorTrait>() {}
pub fn assert_type_is_read_write<T: AsyncRead + AsyncWrite>() {}
pub fn assert_obj_is_sane<T>(_obj: T)
where
T: ConnectorTrait,
T::Output: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static,
for<'a> &'a T::Output: AsyncRead + AsyncWrite + Send + Sync + Unpin,
{
}
}