use super::*;
impl Client {
fn disconnect_connect_barrier_if_needed(&self) {
if matches!(self.connection_state(), ConnectionState::Disconnected) {
let _ = self.disconnect();
}
}
fn ensure_connect_allowed(&self) -> Result<(), Error> {
ensure_connect_not_busy(self.has_connection_flags())
}
fn disconnect_reconnect_barrier(&self) -> Result<(), Error> {
let _ = self.disconnect();
if self.has_connection_flags() {
return Err(Error::CommandFailed {
code: -1,
message: "Reconnect barrier failed: client still has connection flags".to_string(),
});
}
Ok(())
}
pub fn connect_remember(
&self,
host: &str,
tcp: i32,
udp: i32,
encrypted: bool,
) -> Result<(), crate::events::Error> {
self.set_reconnect_params(ConnectParamsOwned::new(host, tcp, udp, encrypted));
self.connect(host, tcp, udp, encrypted)
}
pub fn connect_with_params(
&self,
params: &ConnectParamsOwned,
) -> Result<(), crate::events::Error> {
self.connect(¶ms.host, params.tcp, params.udp, params.encrypted)
}
pub fn connect_from_env(&self) -> Result<(), crate::events::Error> {
let params = ConnectParamsOwned::from_env();
self.connect_remember(¶ms.host, params.tcp, params.udp, params.encrypted)
}
pub fn connect(
&self,
host: &str,
tcp: i32,
udp: i32,
encrypted: bool,
) -> Result<(), crate::events::Error> {
self.ensure_connect_allowed()?;
self.disconnect_connect_barrier_if_needed();
let ok = self
.backend()
.connect(self.ptr.0, host, tcp, udp, encrypted);
if ok {
self.set_connection_state(ConnectionState::Connecting);
self.mark_connect_phase_started();
Ok(())
} else {
Err(crate::events::Error::ConnectFailed)
}
}
pub fn connect_auto(&self, host: &str, tcp: i32, udp: i32) -> Result<(), crate::events::Error> {
self.connect(host, tcp, udp, false)
}
pub fn is_connected(&self) -> bool {
let flags = self.backend().get_flags(self.ptr.0);
(flags & ffi::ClientFlag::CLIENT_CONNECTED as u32) != 0
}
pub fn is_connecting(&self) -> bool {
let flags = self.backend().get_flags(self.ptr.0);
(flags & ffi::ClientFlag::CLIENT_CONNECTING as u32) != 0
}
pub(crate) fn has_connection_flags(&self) -> bool {
self.get_flags().has(crate::types::ClientFlags::CONNECTION)
}
pub fn handle_reconnect(&self, params: &ConnectParams, handler: &mut ReconnectHandler) -> bool {
if !handler.can_attempt() {
return true;
}
if self.disconnect_reconnect_barrier().is_err() {
return true;
}
handler.record_attempt();
let _ = self.connect(params.host, params.tcp, params.udp, params.encrypted);
true
}
pub fn reconnect(
&self,
host: &str,
tcp: i32,
udp: i32,
encrypted: bool,
) -> Result<(), crate::events::Error> {
self.disconnect_reconnect_barrier()?;
self.connect(host, tcp, udp, encrypted)
}
pub fn reconnect_with_params(
&self,
params: &ConnectParamsOwned,
) -> Result<(), crate::events::Error> {
self.reconnect(¶ms.host, params.tcp, params.udp, params.encrypted)
}
pub fn connect_sys_id(
&self,
host: &str,
tcp: i32,
udp: i32,
encrypted: bool,
sys_id: &str,
) -> Result<(), crate::events::Error> {
self.ensure_connect_allowed()?;
self.disconnect_connect_barrier_if_needed();
let ok = self
.backend()
.connect_sys_id(self.ptr.0, host, tcp, udp, encrypted, sys_id);
if ok {
self.set_connection_state(ConnectionState::Connecting);
self.mark_connect_phase_started();
Ok(())
} else {
Err(crate::events::Error::ConnectFailed)
}
}
pub fn reconnect_sys_id(
&self,
host: &str,
tcp: i32,
udp: i32,
encrypted: bool,
sys_id: &str,
) -> Result<(), crate::events::Error> {
self.disconnect_reconnect_barrier()?;
self.connect_sys_id(host, tcp, udp, encrypted, sys_id)
}
pub fn connect_ex(
&self,
host: &str,
tcp: i32,
udp: i32,
bind_ip: &str,
encrypted: bool,
) -> Result<(), crate::events::Error> {
self.ensure_connect_allowed()?;
self.disconnect_connect_barrier_if_needed();
let ok = self
.backend()
.connect_ex(self.ptr.0, host, tcp, udp, bind_ip, encrypted);
if ok {
self.set_connection_state(ConnectionState::Connecting);
self.mark_connect_phase_started();
Ok(())
} else {
Err(crate::events::Error::ConnectFailed)
}
}
pub fn reconnect_ex(
&self,
host: &str,
tcp: i32,
udp: i32,
bind_ip: &str,
encrypted: bool,
) -> Result<(), crate::events::Error> {
self.disconnect_reconnect_barrier()?;
self.connect_ex(host, tcp, udp, bind_ip, encrypted)
}
pub fn disconnect(&self) -> Result<(), crate::events::Error> {
if self.backend().disconnect(self.ptr.0) {
self.clear_all_reconnect_phase_tracking();
self.set_connection_state(ConnectionState::Disconnected);
Ok(())
} else {
Err(crate::events::Error::CommandFailed {
code: -1,
message: "Disconnect failed".to_string(),
})
}
}
}