use std::net::{IpAddr, SocketAddr};
use crate::decode::DecodeLevel;
pub(crate) mod channel;
pub(crate) mod listener;
pub(crate) mod message;
pub(crate) mod requests;
pub(crate) mod task;
#[cfg(feature = "ffi")]
mod ffi_channel;
pub use crate::client::channel::*;
pub use crate::client::listener::*;
pub use crate::client::requests::write_multiple::WriteMultiple;
pub use crate::retry::*;
use crate::ClientOptions;
#[cfg(feature = "ffi")]
pub use ffi_channel::*;
#[cfg(feature = "enable-tls")]
pub use crate::tcp::tls::client::TlsClientConfig;
#[cfg(feature = "enable-tls")]
pub use crate::tcp::tls::*;
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serialization",
derive(serde::Serialize, serde::Deserialize)
)]
pub struct HostAddr {
addr: HostType,
port: u16,
}
impl From<SocketAddr> for HostAddr {
fn from(x: SocketAddr) -> Self {
HostAddr::ip(x.ip(), x.port())
}
}
impl std::fmt::Display for HostAddr {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match &self.addr {
HostType::Dns(x) => write!(f, "{}:{}", x, self.port),
HostType::IpAddr(x) => write!(f, "{}:{}", x, self.port),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serialization",
derive(serde::Serialize, serde::Deserialize)
)]
enum HostType {
Dns(String),
IpAddr(IpAddr),
}
impl HostAddr {
pub fn ip(ip: IpAddr, port: u16) -> Self {
Self {
addr: HostType::IpAddr(ip),
port,
}
}
pub fn dns(name: String, port: u16) -> Self {
Self {
addr: HostType::Dns(name),
port,
}
}
pub(crate) async fn connect(&self) -> std::io::Result<tokio::net::TcpStream> {
match &self.addr {
HostType::Dns(x) => tokio::net::TcpStream::connect((x.as_str(), self.port)).await,
HostType::IpAddr(x) => tokio::net::TcpStream::connect((*x, self.port)).await,
}
}
}
pub fn spawn_tcp_client_task(
host: HostAddr,
max_queued_requests: usize,
retry: Box<dyn RetryStrategy>,
decode_level: DecodeLevel,
listener: Option<Box<dyn Listener<ClientState>>>,
) -> Channel {
let options = ClientOptions::default()
.decode_level(decode_level)
.max_queued_requests(max_queued_requests);
crate::tcp::client::spawn_tcp_channel(
host,
retry,
listener.unwrap_or_else(|| NullListener::create()),
options,
)
}
pub fn spawn_tcp_client_task_with_options(
host: HostAddr,
retry: Box<dyn RetryStrategy>,
listener: Option<Box<dyn Listener<ClientState>>>,
client_options: ClientOptions,
) -> Channel {
crate::tcp::client::spawn_tcp_channel(
host,
retry,
listener.unwrap_or_else(|| NullListener::create()),
client_options,
)
}
pub fn create_tcp_client_task_with_options(
host: HostAddr,
retry: Box<dyn RetryStrategy>,
listener: Option<Box<dyn Listener<ClientState>>>,
client_options: ClientOptions,
) -> (Channel, ClientTask) {
crate::tcp::client::create_tcp_channel(
host,
retry,
listener.unwrap_or_else(|| NullListener::create()),
client_options,
)
}
#[cfg(feature = "serial")]
pub fn spawn_rtu_client_task(
path: &str,
serial_settings: crate::serial::SerialSettings,
max_queued_requests: usize,
retry: Box<dyn RetryStrategy>,
decode: DecodeLevel,
listener: Option<Box<dyn Listener<PortState>>>,
) -> Channel {
Channel::spawn_rtu(
path,
serial_settings,
max_queued_requests,
retry,
decode,
listener,
)
}
#[cfg(feature = "serial")]
pub fn create_rtu_client_task(
path: &str,
serial_settings: crate::serial::SerialSettings,
max_queued_requests: usize,
retry: Box<dyn RetryStrategy>,
decode: DecodeLevel,
listener: Option<Box<dyn Listener<PortState>>>,
) -> (Channel, ClientTask) {
Channel::create_rtu_handle_and_task(
path,
serial_settings,
max_queued_requests,
retry,
decode,
listener,
)
}
#[cfg(feature = "enable-tls")]
pub fn spawn_tls_client_task(
host: HostAddr,
max_queued_requests: usize,
retry: Box<dyn RetryStrategy>,
tls_config: TlsClientConfig,
decode_level: DecodeLevel,
listener: Option<Box<dyn Listener<ClientState>>>,
) -> Channel {
let options = ClientOptions::default()
.decode_level(decode_level)
.max_queued_requests(max_queued_requests);
spawn_tls_channel(
host,
retry,
tls_config,
options,
listener.unwrap_or_else(|| NullListener::create()),
)
}
#[cfg(feature = "enable-tls")]
pub fn create_tls_client_task_with_options(
host: HostAddr,
retry: Box<dyn RetryStrategy>,
tls_config: TlsClientConfig,
listener: Option<Box<dyn Listener<ClientState>>>,
client_options: ClientOptions,
) -> (Channel, ClientTask) {
create_tls_channel(
host,
retry,
tls_config,
client_options,
listener.unwrap_or_else(|| NullListener::create()),
)
}