use std::fmt::Display; use crate::tasks::{IntoTaskErr, Task as BaseTask, TaskOutput}; use serde::Deserialize; use tokio::net::TcpStream; #[derive(Clone, Copy)] pub struct ServerCtx<'a> { pub stream: &'a TcpStream, } pub struct Task<'a>(pub BaseTask>); #[derive(Debug, Deserialize, Clone, Copy, PartialEq)] pub enum Name { GetIp, } impl Display for Name { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "{:?}", self ) } } pub const TASKS: &[Task] = &[ Task( BaseTask { name: Name::GetIp, exec: get_ip, }, ), ]; fn get_ip(_: &[&str], ctx: &ServerCtx) -> TaskOutput { match ctx .stream .peer_addr() { Ok(addr) => Ok( addr.ip() .to_string(), ), Err(e) => Err(e.to_string()), } } impl<'a> TryFrom for &'static Task<'a> { type Error = IntoTaskErr; fn try_from(value: Name) -> Result { for task in TASKS { if task .0 .name == value { return Ok(task); } } Err(IntoTaskErr::NotFound(value.to_string())) } } impl<'a> From> for BaseTask> { fn from(value: Task<'a>) -> Self { value.0 } } impl<'a> AsRef>> for Task<'a> { fn as_ref(&self) -> &BaseTask> { &self.0 } }