use crate::handler::RpcHandlerWrapperTrait;
use crate::{CallError, CallResult, CallSuccess, Error, Resources, RpcId, RpcRequest};
use serde_json::Value;
use std::collections::HashMap;
use std::fmt;
#[derive(Default)]
pub(crate) struct RouterInner {
route_by_name: HashMap<&'static str, Box<dyn RpcHandlerWrapperTrait>>,
}
impl fmt::Debug for RouterInner {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RouterInner")
.field("route_by_name", &self.route_by_name.keys())
.finish()
}
}
impl RouterInner {
pub fn append_dyn(&mut self, name: &'static str, dyn_handler: Box<dyn RpcHandlerWrapperTrait>) {
self.route_by_name.insert(name, dyn_handler);
}
pub fn extend(&mut self, other_router: RouterInner) {
self.route_by_name.extend(other_router.route_by_name);
}
pub async fn call(&self, resources: Resources, rpc_request: RpcRequest) -> CallResult {
let RpcRequest { id, method, params } = rpc_request;
self.call_route(resources, id, method, params).await
}
pub async fn call_route(
&self,
resources: Resources,
id: RpcId,
method: impl Into<String>,
params: Option<Value>,
) -> CallResult {
let method = method.into();
if let Some(route) = self.route_by_name.get(method.as_str()) {
match route.call(resources, params).await {
Ok(value) => Ok(CallSuccess {
id: id.clone(), method: method.clone(),
value,
}),
Err(error) => Err(CallError { id, method, error }),
}
} else {
Err(CallError {
id,
method,
error: Error::MethodUnknown,
})
}
}
}