use super::{Decider, DeciderHooks};
use crate::actions::Action;
use crate::metadata::AsAny;
use crate::observers::{Observers, ResponseObserver};
use crate::responses::Response;
use crate::state::SharedState;
use crate::std_ext::tuple::Named;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(clippy::derive_partial_eq_without_eq)] pub struct ContentLengthDecider<F>
where
F: Fn(usize, usize, &SharedState) -> Action + 'static,
{
comparator: F,
content_length: usize,
}
impl<F> ContentLengthDecider<F>
where
F: Fn(usize, usize, &SharedState) -> Action + 'static,
{
pub const fn new(content_length: usize, comparator: F) -> Self {
Self {
comparator,
content_length,
}
}
}
impl<O, R, F> DeciderHooks<O, R> for ContentLengthDecider<F>
where
O: Observers<R>,
R: Response,
F: Fn(usize, usize, &SharedState) -> Action + Sync + Send + Clone + 'static,
{
}
impl<O, R, F> Decider<O, R> for ContentLengthDecider<F>
where
O: Observers<R>,
R: Response,
F: Fn(usize, usize, &SharedState) -> Action + Clone + 'static,
{
fn decide_with_observers(&mut self, state: &SharedState, observers: &O) -> Option<Action> {
if let Some(observer) = observers.match_name::<ResponseObserver<R>>("ResponseObserver") {
let observed_content_length = observer.content_length();
return Some((self.comparator)(
self.content_length,
observed_content_length,
state,
));
}
None
}
}
impl<F> AsAny for ContentLengthDecider<F>
where
F: Fn(usize, usize, &SharedState) -> Action + 'static,
{
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl<F> Named for ContentLengthDecider<F>
where
F: Fn(usize, usize, &SharedState) -> Action,
{
fn name(&self) -> &'static str {
"ContentLengthDecider"
}
}