use crates::serde_json::Value;
use director::Director;
use error::Result;
use std::error;
#[derive(Debug)]
pub enum HandlerResult {
Accept,
Defer(String),
Reject(String),
Fail(Box<error::Error>),
Restart,
Done,
}
impl HandlerResult {
pub fn combine(self, other: Self) -> Self {
match (self, other) {
(HandlerResult::Accept, next) |
(next, HandlerResult::Accept) => next,
(HandlerResult::Done, _) |
(_, HandlerResult::Done) => HandlerResult::Done,
(HandlerResult::Restart, _) |
(_, HandlerResult::Restart) => HandlerResult::Restart,
(HandlerResult::Defer(left), HandlerResult::Defer(right)) => {
HandlerResult::Defer(format!("{}\n{}", left, right))
},
(defer @ HandlerResult::Defer(_), _) |
(_, defer @ HandlerResult::Defer(_)) => defer,
(fail @ HandlerResult::Fail(_), _) |
(_, fail @ HandlerResult::Fail(_)) => fail,
(HandlerResult::Reject(left), HandlerResult::Reject(right)) => {
HandlerResult::Reject(format!("{}\n{}", left, right))
},
}
}
}
pub trait Handler {
fn add_to_director<'a>(&'a self, director: &mut Director<'a>) -> Result<()>;
fn handle(&self, kind: &str, object: &Value) -> Result<HandlerResult>;
fn retry_limit(&self, _kind: &str) -> usize {
5
}
fn handle_retry(&self, kind: &str, object: &Value, reasons: Vec<String>)
-> Result<HandlerResult> {
if reasons.len() > self.retry_limit(kind) {
return Ok(HandlerResult::Reject(format!("retry limit ({}) reached for {}",
reasons.len(),
kind)));
}
self.handle(kind, object)
}
}