use super::route::RPCRoute;
use crate::tarantool::error::TarantoolErrorCode;
use crate::tarantool::set_error;
use crate::tarantool::tuple::{FunctionArgs, FunctionCtx, Tuple};
use std::cell::RefCell;
use std::collections::HashMap;
use std::os::raw::c_int;
pub struct Server {
routes: RefCell<HashMap<String, Box<dyn RPCRoute>>>,
}
#[allow(clippy::new_without_default)]
impl Server {
pub fn new() -> Self {
Self {
routes: RefCell::new(HashMap::new()),
}
}
pub fn register(&self, route: Box<dyn RPCRoute>) {
self.routes
.borrow_mut()
.insert(route.path().to_string(), route);
}
pub fn handle(&self, ctx: FunctionCtx, args: FunctionArgs) -> c_int {
let tup = Tuple::from(args);
let path = match tup.field::<String>(0).unwrap_or(None) {
Some(p) => p,
None => {
set_error!(
TarantoolErrorCode::ProcC,
"path not exists in request (invalid request)"
);
return -1;
}
};
let routes = self.routes.borrow();
let handler = match routes.get(&path) {
Some(h) => h,
None => {
set_error!(TarantoolErrorCode::ProcC, "path {} not found", path);
return -1;
}
};
handler.handle(ctx, tup)
}
}