use std::{net::SocketAddr, sync::Arc};
use bytes::{Buf, Bytes, BytesMut};
use crate::{
app::{AsyncFunc, ClientsStructType, TaskBody},
const_config::{DEFAULT_MESSAGE_HEADER_MARK, DEFAULT_MESSAGE_TAIL_MARK},
};
#[cfg(any(feature = "server", feature = "client"))]
#[derive(Clone)]
pub struct HandlerResult {
is_send: bool,
is_heart: bool,
result_data: Option<(u16, Bytes)>,
addrs: Option<Vec<SocketAddr>>,
message_header_mark: Option<u16>,
message_tail_mark: Option<u16>,
}
impl HandlerResult {
#[cfg(feature = "server")]
pub fn new_with_send(
method_id: u16,
response_data: Bytes,
target_addrs: Vec<SocketAddr>,
) -> Self {
Self {
is_send: true,
is_heart: false,
result_data: Some((method_id, response_data)),
addrs: Some(target_addrs),
message_header_mark: None,
message_tail_mark: None,
}
}
#[cfg(feature = "client")]
pub fn new_with_send_to_server(method_id: u16, response_data: Bytes) -> Self {
Self {
is_send: true,
is_heart: false,
result_data: Some((method_id, response_data)),
addrs: None,
message_header_mark: None,
message_tail_mark: None,
}
}
#[cfg(feature = "client")]
pub(crate) fn new_with_send_heart_to_server() -> Self {
Self {
is_send: true,
is_heart: true,
result_data: Some((0_u16, Bytes::new())),
addrs: None,
message_header_mark: None,
message_tail_mark: None,
}
}
#[cfg(any(feature = "server", feature = "client"))]
pub fn new_without_send() -> Self {
Self {
is_send: false,
is_heart: false,
result_data: None,
addrs: None,
message_header_mark: None,
message_tail_mark: None,
}
}
pub(crate) fn get_is_send(&self) -> bool {
self.is_send
}
pub(crate) fn get_addrs(&self) -> Option<Vec<SocketAddr>> {
self.addrs.clone()
}
pub(crate) fn is_with_mark(&self) -> bool {
if self.message_header_mark.is_some() && self.message_tail_mark.is_some() {
true
} else {
false
}
}
pub(crate) fn set_marks(&mut self, message_header_mark: u16, message_tail_mark: u16) {
self.message_header_mark = Some(message_header_mark);
self.message_tail_mark = Some(message_tail_mark);
}
pub(crate) fn get_response_data(&self) -> Option<Bytes> {
match self.result_data.clone() {
Some((method_id, bytes)) => {
let mut bytes_mut = BytesMut::new();
if let Some(mark) = self.message_header_mark {
bytes_mut.extend_from_slice(&mark.to_le_bytes());
} else {
bytes_mut.extend_from_slice(&DEFAULT_MESSAGE_HEADER_MARK.to_le_bytes());
}
let mut msg_len = 0_u64;
let constructor_id = if self.is_heart {
2_u8.to_le_bytes()
} else {
1_u8.to_le_bytes()
};
let method_id_bytes = method_id.to_le_bytes();
let bytes_body_len = bytes.len();
let msg_tail_len = 2_u64;
msg_len = constructor_id.len() as u64
+ method_id_bytes.len() as u64
+ bytes_body_len as u64
+ msg_tail_len;
bytes_mut.extend_from_slice(&msg_len.to_le_bytes());
bytes_mut.extend_from_slice(&constructor_id);
bytes_mut.extend_from_slice(&method_id_bytes);
bytes_mut.extend_from_slice(&bytes);
if let Some(mark) = self.message_tail_mark {
bytes_mut.extend_from_slice(&mark.to_le_bytes());
} else {
bytes_mut.extend_from_slice(&DEFAULT_MESSAGE_TAIL_MARK.to_le_bytes());
}
Some(bytes_mut.copy_to_bytes(bytes_mut.len()))
}
None => None,
}
}
}
pub(crate) trait IHandlerCombinedTrait: IHandlerMethod {
async fn execute(
&mut self,
clients: ClientsStructType,
handler_method: Arc<AsyncFunc>,
thread_pool: TaskBody,
) {
self.handler(handler_method, thread_pool, clients).await;
}
}
pub(crate) trait IHandlerMethod {
async fn handler(
&mut self,
handler_method: Arc<AsyncFunc>,
thread_pool: TaskBody,
clients: ClientsStructType,
);
}