1#![doc = include_doc::function_body!("tests/doc.rs", router_example, [my_add, MyAdd])]
9use std::sync::Arc;
11
12use actix_web::{
13 dev::{ServiceFactory, ServiceRequest},
14 web::{self},
15 App, Error, HttpRequest,
16};
17use arpy::FnRemote;
18use arpy_server::{FnRemoteBody, WebSocketRouter};
19use websocket::WebSocketHandler;
20
21pub mod http;
22mod websocket;
23
24pub trait RpcApp {
27 fn http_rpc_route<F, T>(self, prefix: &str, f: F) -> Self
32 where
33 F: FnRemoteBody<T> + 'static,
34 T: FnRemote + 'static;
35
36 fn ws_rpc_route(self, path: &str, router: WebSocketRouter, max_in_flight: usize) -> Self;
38}
39
40impl<S> RpcApp for App<S>
41where
42 S: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,
43{
44 fn http_rpc_route<F, T>(self, prefix: &str, f: F) -> Self
45 where
46 F: FnRemoteBody<T> + 'static,
47 T: FnRemote + 'static,
48 {
49 let id = T::ID;
50 let f = Arc::new(f);
51
52 self.route(
53 &format!("{prefix}/{id}"),
54 web::post().to(move |request| http::handler(f.clone(), request)),
55 )
56 }
57
58 fn ws_rpc_route(self, path: &str, router: WebSocketRouter, max_in_flight: usize) -> Self {
59 let handler = WebSocketHandler::new(router, max_in_flight);
60 self.route(
61 path,
62 web::get().to(move |req: HttpRequest, body: web::Payload| {
63 let handler = handler.clone();
64 websocket::handler(handler, req, body)
65 }),
66 )
67 }
68}