razor_rpc/server/
service.rs1use super::task::APIServerReq;
2use crate::{Codec, error::RpcIntErr};
3use ahash::AHashMap;
4use std::sync::Arc;
5
6pub trait ServiceStatic<C: Codec>: Send + Sync + 'static + Sized {
14 const SERVICE_NAME: &'static str;
16
17 fn serve(&self, req: APIServerReq<C>) -> impl Future<Output = ()> + Send + Sized;
38}
39
40impl<S: ServiceStatic<C>, C: Codec> ServiceStatic<C> for Arc<S> {
41 const SERVICE_NAME: &'static str = S::SERVICE_NAME;
42
43 #[inline(always)]
44 fn serve(&self, req: APIServerReq<C>) -> impl Future<Output = ()> + Send + Sized {
45 self.as_ref().serve(req)
46 }
47}
48
49#[async_trait::async_trait]
55pub trait ServiceDyn<C: Codec>: Send + Sync + 'static {
56 fn get_service_name(&self) -> &'static str;
57
58 async fn serve_dyn(&self, req: APIServerReq<C>);
59}
60
61#[async_trait::async_trait]
62impl<S: ServiceStatic<C>, C: Codec> ServiceDyn<C> for S {
63 #[inline(always)]
64 fn get_service_name(&self) -> &'static str {
65 <Self as ServiceStatic<C>>::SERVICE_NAME
66 }
67
68 #[inline(always)]
69 async fn serve_dyn(&self, req: APIServerReq<C>) {
70 self.serve(req).await
71 }
72}
73
74pub struct ServiceMuxDyn<C: Codec> {
78 map: AHashMap<&'static str, Arc<dyn ServiceDyn<C>>>,
79}
80
81impl<C: Codec> Default for ServiceMuxDyn<C> {
82 fn default() -> Self {
83 Self { map: Default::default() }
84 }
85}
86
87impl<C: Codec> ServiceMuxDyn<C> {
88 #[inline]
89 pub fn new() -> Self {
90 Default::default()
91 }
92
93 #[inline]
94 pub fn add(&mut self, service: Arc<dyn ServiceDyn<C>>) {
95 self.map.insert(service.get_service_name(), service);
96 }
97}
98
99impl<C: Codec> ServiceStatic<C> for ServiceMuxDyn<C> {
100 const SERVICE_NAME: &'static str = "";
101
102 #[inline(always)]
103 async fn serve(&self, req: APIServerReq<C>) {
104 if let Some(service) = self.map.get(req.service.as_str()) {
105 service.serve_dyn(req).await
106 } else {
107 req.set_rpc_error(RpcIntErr::Service);
108 }
109 }
110}