use crate::requests::Request;
use crate::responses::Response;
use crate::std_ext::tuple::{MatchName, Named};
use crate::ObserversList;
mod response;
pub use self::response::ResponseObserver;
pub trait Observer {}
pub trait ObserverHooks<R>
where
R: Response,
{
fn pre_send_hook(&mut self, _request: &Request) {}
fn post_send_hook(&mut self, _response: R) {}
}
pub trait Observers<R>: MatchName
where
R: Response,
{
fn call_pre_send_hooks(&mut self, _request: &Request) {}
fn call_post_send_hooks(&mut self, _response: R)
where
R: Response,
{
}
}
impl<R> Observers<R> for () where R: Response {}
impl<Head, Tail, R> Observers<R> for (Head, Tail)
where
R: Response + Clone,
Head: Named + ObserverHooks<R>,
Tail: Observers<R> + ObserversList,
{
fn call_pre_send_hooks(&mut self, request: &Request) {
self.0.pre_send_hook(request);
self.1.call_pre_send_hooks(request);
}
fn call_post_send_hooks(&mut self, response: R) {
self.0.post_send_hook(response.clone());
self.1.call_post_send_hooks(response);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::build_observers;
use crate::requests::Request;
use crate::responses::AsyncResponse;
use std::time::Duration;
struct TestObserver {}
impl Named for TestObserver {
#[allow(clippy::unnecessary_literal_bound)]
fn name(&self) -> &str {
"TestObserver"
}
}
impl Observer for TestObserver {}
impl ObserverHooks<AsyncResponse> for TestObserver {}
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn observer_hooks_can_be_called_recursively() {
let mut observer = TestObserver {};
assert_eq!(observer.name(), "TestObserver");
let request = Request::new();
let elapsed = Duration::from_secs(1);
let reqwest_response = http::response::Response::new("{\"stuff\":\"things\"}");
let response = AsyncResponse::try_from_reqwest_response(
request.clone(),
reqwest_response.into(),
elapsed,
)
.await
.unwrap();
observer.pre_send_hook(&request);
observer.post_send_hook(response.clone());
let observer2 = TestObserver {};
let mut observers_list = build_observers!(observer, observer2);
observers_list.call_pre_send_hooks(&request);
observers_list.call_post_send_hooks(response);
}
}