use std::future::Future;
use std::sync::Arc;
use futures_util::future::BoxFuture;
use crate::errors::CrawlError;
use crate::request::Request;
pub trait RequestHandler<C>: Send + Sync + 'static {
fn handle(&self, ctx: C) -> BoxFuture<'static, Result<(), CrawlError>>;
}
impl<C, F, Fut> RequestHandler<C> for F
where
F: Fn(C) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<(), CrawlError>> + Send + 'static,
{
fn handle(&self, ctx: C) -> BoxFuture<'static, Result<(), CrawlError>> {
Box::pin((self)(ctx))
}
}
pub trait Middleware<C>: Send + Sync + 'static {
fn run(&self, ctx: C) -> BoxFuture<'static, Result<C, CrawlError>>;
}
impl<C, F, Fut> Middleware<C> for F
where
F: Fn(C) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<C, CrawlError>> + Send + 'static,
{
fn run(&self, ctx: C) -> BoxFuture<'static, Result<C, CrawlError>> {
Box::pin((self)(ctx))
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct FailedRequestContext {
pub request: Arc<Request>,
pub error: Arc<CrawlError>,
pub retry_count: u32,
}
impl FailedRequestContext {
pub fn new(request: Arc<Request>, error: Arc<CrawlError>, retry_count: u32) -> Self {
Self {
request,
error,
retry_count,
}
}
}
pub trait FailedRequestHandler: Send + Sync + 'static {
fn handle(&self, ctx: FailedRequestContext) -> BoxFuture<'static, Result<(), CrawlError>>;
}
impl<F, Fut> FailedRequestHandler for F
where
F: Fn(FailedRequestContext) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<(), CrawlError>> + Send + 'static,
{
fn handle(&self, ctx: FailedRequestContext) -> BoxFuture<'static, Result<(), CrawlError>> {
Box::pin((self)(ctx))
}
}