use super::backend_handler::BackEndHandler;
use crate::authenticators::ApplicationName;
use parsec_interface::requests::request::Request;
use parsec_interface::requests::ProviderID;
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_name: Option<ApplicationName>,
) -> Response {
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 {
backend.execute_request(request, app_name)
}
} 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"))?,
})
}
}