use std::time::Duration; use std::net::SocketAddr; use fire_stream_api::{ server::{Server, Config as ServerConfig}, client::{Client, Config as ClientConfig} }; use tokio::net::{TcpListener, TcpStream}; use crypto::signature::Keypair; mod api { use std::fmt; use serde::{Serialize, Deserialize}; use fire_stream_api::{ IntoMessage, FromMessage, Action, error::{ApiError, RequestError, MessageError}, request::Request, message::{IntoMessage, FromMessage, Message, PacketBytes} }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Action)] #[repr(u16)] pub enum Action { RawReq = 1 } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(IntoMessage, FromMessage)] #[message(json)] pub enum Error { MyError, RequestError(String), MessageError(String) } impl ApiError for Error { fn from_request_error(e: RequestError) -> Self { Self::RequestError(e.to_string()) } fn from_message_error(e: MessageError) -> Self { Self::MessageError(e.to_string()) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(self, f) } } impl std::error::Error for Error {} // raw requests #[derive(Debug, Clone)] pub struct RawReq { inner: Message } impl RawReq { pub fn new(len: usize) -> Self { let mut msg = Message::new(); msg.body_mut().resize(len); Self { inner: msg } } pub fn body_len(&self) -> usize { self.inner.body().len() } } impl IntoMessage for RawReq where B: PacketBytes { fn into_message(self) -> Result, MessageError> { Ok(self.inner) } } impl FromMessage for RawReq where B: PacketBytes { fn from_message(msg: Message) -> Result { Ok(Self { inner: msg }) } } #[derive(Debug, Clone, Serialize, Deserialize, IntoMessage, FromMessage)] #[message(json)] pub struct RawResp { pub status: String } impl Request for RawReq { type Action = Action; type Response = RawResp; type Error = Error; const ACTION: Action = Action::RawReq; } } mod handlers { use crate::api::*; use fire_stream_api::{api}; type Result = std::result::Result; #[api(RawReq)] pub fn raw_request(req: RawReq) -> Result { Ok(RawResp { status: format!("worked {}", req.body_len()) }) } } struct MyAddr(SocketAddr); #[tokio::test] async fn main() { let listener = TcpListener::bind(("127.0.0.1", 0)).await.unwrap(); let addr = listener.local_addr().unwrap(); let priv_key = Keypair::new(); let pub_key = priv_key.public().clone(); let my_addr = MyAddr(addr.clone()); tokio::spawn(async move { // spawn server let mut server = Server::new_encrypted(listener, ServerConfig { timeout: Duration::from_secs(10), body_limit: 0 }, priv_key); server.register_data(my_addr); server.register_request(handlers::raw_request); server.run().await.unwrap(); }); // now connect let stream = TcpStream::connect(addr.clone()).await.unwrap(); let client = Client::new_encrypted(stream, ClientConfig { timeout: Duration::from_secs(10), body_limit: 0 }, None, pub_key); let e = client.request(api::RawReq::new(10)).await.unwrap(); assert_eq!(e.status, "worked 10"); client.close().await.unwrap(); }