#![allow(clippy::type_repetition_in_bounds)]
use std::marker::PhantomData;
use super::{Decider, DeciderHooks};
use crate::actions::Action;
use crate::metadata::AsAny;
use crate::observers::{Observers, ResponseObserver};
use crate::requests::Request;
use crate::responses::Response;
use crate::state::SharedState;
use crate::std_ext::tuple::Named;
use regex::bytes::Regex;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct RequestRegexDecider<F>
where
F: Fn(&Regex, &Request, &SharedState) -> Action,
{
comparator: F,
#[cfg_attr(feature = "serde", serde(with = "serde_regex"))]
regex: Regex,
}
impl<F> RequestRegexDecider<F>
where
F: Fn(&Regex, &Request, &SharedState) -> Action,
{
pub fn new(regex: &str, comparator: F) -> Self {
Self {
regex: Regex::new(regex).unwrap(),
comparator,
}
}
pub const fn with_regex(regex: Regex, comparator: F) -> Self {
Self { comparator, regex }
}
}
impl<O, R, F> DeciderHooks<O, R> for RequestRegexDecider<F>
where
O: Observers<R>,
R: Response + Sync + Send + Clone,
F: Fn(&Regex, &Request, &SharedState) -> Action + Sync + Send + Clone + 'static,
{
}
impl<O, R, F> Decider<O, R> for RequestRegexDecider<F>
where
O: Observers<R>,
R: Response + Clone,
F: Fn(&Regex, &Request, &SharedState) -> Action + Clone + 'static,
{
fn decide_with_request(&mut self, state: &SharedState, request: &Request) -> Option<Action> {
Some((self.comparator)(&self.regex, request, state))
}
}
impl<F> AsAny for RequestRegexDecider<F>
where
F: Fn(&Regex, &Request, &SharedState) -> Action + 'static,
{
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl<F> Named for RequestRegexDecider<F>
where
F: Fn(&Regex, &Request, &SharedState) -> Action,
{
fn name(&self) -> &'static str {
"RequestRegexDecider"
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ResponseRegexDecider<F, R>
where
R: Response,
F: Fn(&Regex, &ResponseObserver<R>, &SharedState) -> Action,
{
comparator: F,
#[cfg_attr(feature = "serde", serde(with = "serde_regex"))]
regex: Regex,
marker: PhantomData<R>,
}
impl<F, R> ResponseRegexDecider<F, R>
where
F: Fn(&Regex, &ResponseObserver<R>, &SharedState) -> Action,
R: Response,
{
pub fn new(regex: &str, comparator: F) -> Self {
Self {
regex: Regex::new(regex).unwrap(),
comparator,
marker: PhantomData,
}
}
pub const fn with_regex(regex: Regex, comparator: F) -> Self {
Self {
regex,
comparator,
marker: PhantomData,
}
}
}
impl<O, R, F> DeciderHooks<O, R> for ResponseRegexDecider<F, R>
where
O: Observers<R>,
R: Response + Send + Sync + Clone + 'static,
F: Fn(&Regex, &ResponseObserver<R>, &SharedState) -> Action + Sync + Send + Clone + 'static,
{
}
impl<O, R, F> Decider<O, R> for ResponseRegexDecider<F, R>
where
O: Observers<R>,
R: Response + Clone + 'static,
F: Fn(&Regex, &ResponseObserver<R>, &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") {
return Some((self.comparator)(&self.regex, observer, state));
}
None
}
}
impl<F, R> AsAny for ResponseRegexDecider<F, R>
where
R: Response + 'static,
F: Fn(&Regex, &ResponseObserver<R>, &SharedState) -> Action + 'static,
{
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl<F, R> Named for ResponseRegexDecider<F, R>
where
R: Response + 'static,
F: Fn(&Regex, &ResponseObserver<R>, &SharedState) -> Action,
{
fn name(&self) -> &'static str {
"ResponseRegexDecider"
}
}