#![doc = include_doc::function_body!("tests/doc.rs", router_example, [my_add, MyAdd])]
use std::sync::Arc;
use actix_web::{
dev::{ServiceFactory, ServiceRequest},
web::{self},
App, Error, HttpRequest,
};
use arpy::FnRemote;
use arpy_server::{FnRemoteBody, WebSocketRouter};
use websocket::WebSocketHandler;
pub mod http;
mod websocket;
pub trait RpcApp {
fn http_rpc_route<F, T>(self, prefix: &str, f: F) -> Self
where
F: FnRemoteBody<T> + 'static,
T: FnRemote + 'static;
fn ws_rpc_route(self, path: &str, router: WebSocketRouter, max_in_flight: usize) -> Self;
}
impl<S> RpcApp for App<S>
where
S: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,
{
fn http_rpc_route<F, T>(self, prefix: &str, f: F) -> Self
where
F: FnRemoteBody<T> + 'static,
T: FnRemote + 'static,
{
let id = T::ID;
let f = Arc::new(f);
self.route(
&format!("{prefix}/{id}"),
web::post().to(move |request| http::handler(f.clone(), request)),
)
}
fn ws_rpc_route(self, path: &str, router: WebSocketRouter, max_in_flight: usize) -> Self {
let handler = WebSocketHandler::new(router, max_in_flight);
self.route(
path,
web::get().to(move |req: HttpRequest, body: web::Payload| {
let handler = handler.clone();
websocket::handler(handler, req, body)
}),
)
}
}