use crate::{FallbackEvent, FallbackStrategy, HandlePredicate};
use tower_resilience_core::{EventListeners, FnListener};
pub struct FallbackConfig<Req, Res, E> {
pub(crate) name: String,
pub(crate) strategy: FallbackStrategy<Req, Res, E>,
pub(crate) handle_predicate: Option<HandlePredicate<E>>,
pub(crate) event_listeners: EventListeners<FallbackEvent>,
}
pub struct FallbackConfigBuilder<Req, Res, E> {
name: String,
strategy: Option<FallbackStrategy<Req, Res, E>>,
handle_predicate: Option<HandlePredicate<E>>,
event_listeners: EventListeners<FallbackEvent>,
}
impl<Req, Res, E> Default for FallbackConfigBuilder<Req, Res, E> {
fn default() -> Self {
Self::new()
}
}
impl<Req, Res, E> FallbackConfigBuilder<Req, Res, E> {
pub fn new() -> Self {
Self {
name: "fallback".to_string(),
strategy: None,
handle_predicate: None,
event_listeners: EventListeners::new(),
}
}
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = name.into();
self
}
pub fn value(mut self, value: Res) -> Self
where
Res: Clone,
{
self.strategy = Some(FallbackStrategy::Value(value));
self
}
pub fn value_fn<F>(mut self, f: F) -> Self
where
F: Fn() -> Res + Send + Sync + 'static,
{
self.strategy = Some(FallbackStrategy::ValueFn(std::sync::Arc::new(f)));
self
}
pub fn from_error<F>(mut self, f: F) -> Self
where
F: Fn(&E) -> Res + Send + Sync + 'static,
{
self.strategy = Some(FallbackStrategy::FromError(std::sync::Arc::new(f)));
self
}
pub fn from_request_error<F>(mut self, f: F) -> Self
where
F: Fn(&Req, &E) -> Res + Send + Sync + 'static,
{
self.strategy = Some(FallbackStrategy::FromRequestError(std::sync::Arc::new(f)));
self
}
pub fn service<S, Fut>(mut self, service: S) -> Self
where
S: Fn(Req) -> Fut + Send + Sync + 'static,
Fut: std::future::Future<Output = Result<Res, E>> + Send + 'static,
{
self.strategy = Some(FallbackStrategy::Service(std::sync::Arc::new(move |req| {
Box::pin(service(req))
})));
self
}
pub fn exception<F>(mut self, f: F) -> Self
where
F: Fn(E) -> E + Send + Sync + 'static,
{
self.strategy = Some(FallbackStrategy::Exception(std::sync::Arc::new(f)));
self
}
pub fn handle<F>(mut self, predicate: F) -> Self
where
F: Fn(&E) -> bool + Send + Sync + 'static,
{
self.handle_predicate = Some(std::sync::Arc::new(predicate));
self
}
pub fn on_event<F>(mut self, listener: F) -> Self
where
F: Fn(&FallbackEvent) + Send + Sync + 'static,
{
self.event_listeners.add(FnListener::new(listener));
self
}
pub fn build(self) -> crate::FallbackLayer<Req, Res, E> {
let config = FallbackConfig {
name: self.name,
strategy: self.strategy.expect("fallback strategy must be set"),
handle_predicate: self.handle_predicate,
event_listeners: self.event_listeners,
};
crate::FallbackLayer::new(config)
}
}