lynn_tcp 1.1.8

Lightweight asynchronous TCP framework
Documentation
mod impl_for_context;

use std::{future::Future, marker::PhantomData, net::SocketAddr, pin::Pin};

use crate::{
    app::ClientsStruct,
    lynn_tcp_dependents::{HandlerResult, InputBufVO},
};

#[derive(Clone)]
pub(crate) struct HandlerContext {
    input_buf_vo: InputBufVO,
    clients_context: ClientsContext,
}

impl HandlerContext {
    pub(crate) fn new(input_buf_vo: InputBufVO, clients_context: ClientsContext) -> Self {
        HandlerContext {
            input_buf_vo,
            clients_context,
        }
    }
}

#[derive(Clone)]
#[cfg(feature = "server")]
pub struct ClientsContext {
    clients: Option<ClientsStruct>,
}

impl ClientsContext {
    pub(crate) fn new(clients: ClientsStruct) -> Self {
        Self {
            clients: Some(clients),
        }
    }

    pub(crate) fn new_none() -> Self {
        Self { clients: None }
    }

    #[cfg(feature = "server")]
    pub async fn get_all_clients_addrs(&self) -> Vec<SocketAddr> {
        let mut result = Vec::new();
        if let Some(clients) = &self.clients {
            let clients = clients.0.read().await;
            for client in clients.iter() {
                result.push(client.0.clone());
            }
        }
        result
    }
}

pub(crate) trait IHandler: Send + Sync + 'static {
    fn handler(
        &self,
        context: HandlerContext,
    ) -> Pin<Box<dyn Future<Output = HandlerResult> + Send + 'static>>;
}

impl<Param: SystemParam, F: SystemParamFunction<Param>> IHandler for FunctionSystem<F, Param> {
    fn handler(
        &self,
        context: HandlerContext,
    ) -> Pin<Box<dyn Future<Output = HandlerResult> + Send + 'static>> {
        let param = Param::State::get_param(&self.state, &context);
        Box::pin(self.func.run(param))
    }
}

pub(crate) trait SystemParam: Send + Sync + 'static {
    type State: SystemParamState<Item = Self>;
}

pub(crate) trait SystemParamState: Send + Sync + 'static {
    type Item: SystemParam<State = Self>;

    fn init() -> Self;

    fn get_param(state: &Self, context: &HandlerContext) -> Self::Item;
}

#[derive(Clone)]
pub(crate) struct FunctionSystem<F, Param>
where
    Param: SystemParam + 'static,
    F: SystemParamFunction<Param> + 'static,
{
    func: F,
    state: Param::State,
    _maker: PhantomData<Param>,
}

pub(crate) trait SystemParamFunction<Param>: Send + Sync + 'static {
    fn run(&self, params: Param) -> Pin<Box<dyn Future<Output = HandlerResult> + Send + 'static>>;
}

pub(crate) trait IntoSystem<Param>: Sized {
    type System: IHandler;
    fn to_system(self) -> Self::System;
}

impl<Param: SystemParam + 'static, F: SystemParamFunction<Param> + 'static> IntoSystem<Param>
    for F
{
    type System = FunctionSystem<F, Param>;

    fn to_system(self) -> Self::System {
        FunctionSystem {
            func: self,
            state: Param::State::init(),
            _maker: PhantomData,
        }
    }
}