use super::backend_handler::BackEndHandler;
use crate::authenticators::Application;
use log::trace;
use parsec_interface::requests::ProviderId;
use parsec_interface::requests::request::Request;
use parsec_interface::requests::{Response, ResponseStatus};
use std::collections::HashMap;
use std::io::{Error, ErrorKind, Result};
#[derive(Debug)]
pub struct Dispatcher {
backends: HashMap<ProviderId, BackEndHandler>,
}
impl Dispatcher {
pub fn dispatch_request(&self, request: Request, app: Option<Application>) -> Response {
trace!("dispatch_request ingress");
if let Some(backend) = self.backends.get(&request.header.provider) {
if let Err(status) = backend.is_capable(&request) {
Response::from_request_header(request.header, status)
} else {
{
let response = backend.execute_request(request, app);
trace!("execute_request egress");
response
}
}
} else {
Response::from_request_header(request.header, ResponseStatus::ProviderNotRegistered)
}
}
}
#[derive(Debug, Default)]
pub struct DispatcherBuilder {
backends: Option<HashMap<ProviderId, BackEndHandler>>,
}
impl DispatcherBuilder {
pub fn new() -> Self {
DispatcherBuilder { backends: None }
}
pub fn with_backend(
mut self,
provider_id: ProviderId,
backend_handler: BackEndHandler,
) -> Self {
let mut backends = self.backends.unwrap_or_default();
let _ = backends.insert(provider_id, backend_handler);
self.backends = Some(backends);
self
}
pub fn with_backends(mut self, new_backends: HashMap<ProviderId, BackEndHandler>) -> Self {
let mut backends = self.backends.unwrap_or_default();
backends.extend(new_backends);
self.backends = Some(backends);
self
}
pub fn build(self) -> Result<Dispatcher> {
Ok(Dispatcher {
backends: self
.backends
.ok_or_else(|| Error::new(ErrorKind::InvalidData, "backends is missing"))?,
})
}
}