use crate::service::ServiceError;
use actix_web::web;
use serde::Serialize;
use serde::de::DeserializeOwned;
use std::sync::Mutex;
use super::handle_request;
pub struct ServiceScope<S> {
scope: actix_web::Scope,
service: web::Data<Mutex<S>>,
}
impl<S: 'static> ServiceScope<S> {
pub fn new(path: &str, service: S) -> Self {
Self {
scope: web::scope(path),
service: web::Data::new(Mutex::new(service)),
}
}
}
impl<S: 'static> ServiceScope<S> {
pub fn call<I, O, F>(mut self, path: &str, f: F) -> Self
where
I: DeserializeOwned + 'static,
O: Serialize + 'static,
F: Fn(&mut S, I) -> Result<O, ServiceError> + 'static + Clone,
{
let service: web::Data<Mutex<S>> = self.service.clone();
let handler = move |body: web::Bytes| {
let service: web::Data<Mutex<S>> = service.clone();
let f: F = f.clone();
async move {
let mut service = service.lock().unwrap_or_else(|e| e.into_inner());
handle_request::<I, O, _>(&body, |req| f(&mut *service, req))
}
};
self.scope = self.scope.route(path, web::post().to(handler));
self
}
}
impl<S: 'static> ServiceScope<S> {
pub fn build(self) -> actix_web::Scope {
self.scope.app_data(self.service)
}
}