use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use crate::error::ApiError;
use crate::types::{
CrawlRequest, CrawlSummary, Document, ExtractRequest, MapLink, MapRequest, ScrapeOptions,
SearchRequest,
};
use serde_json::Value;
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
pub trait Engine: Send + Sync + 'static {
fn scrape<'a>(
&'a self,
url: &'a str,
opts: &'a ScrapeOptions,
) -> BoxFuture<'a, Result<Document, ApiError>>;
fn map<'a>(&'a self, _req: &'a MapRequest) -> BoxFuture<'a, Result<Vec<MapLink>, ApiError>> {
Box::pin(async { Err(ApiError::unsupported("map is not available in this build")) })
}
fn crawl<'a>(
&'a self,
_req: &'a CrawlRequest,
_sink: Arc<dyn CrawlSink>,
) -> BoxFuture<'a, Result<(), ApiError>> {
Box::pin(async {
Err(ApiError::unsupported(
"crawl is not available in this build",
))
})
}
fn search<'a>(&'a self, _req: &'a SearchRequest) -> BoxFuture<'a, Result<Value, ApiError>> {
Box::pin(async {
Err(ApiError::unsupported(
"search is not configured: set [search] in pagesift.toml",
))
})
}
fn extract<'a>(&'a self, _req: &'a ExtractRequest) -> BoxFuture<'a, Result<Value, ApiError>> {
Box::pin(async {
Err(ApiError::unsupported(
"extract needs an LLM: set [llm] in pagesift.toml",
))
})
}
fn supported_formats(&self) -> &'static [&'static str] {
&["markdown", "html", "rawHtml", "links", "images"]
}
fn supports_actions(&self) -> bool {
false
}
}
pub trait CrawlSink: Send + Sync {
fn page(&self, doc: Document) -> BoxFuture<'_, ()>;
fn error<'a>(&'a self, url: &'a str, err: ApiError) -> BoxFuture<'a, ()>;
fn total(&self, total: usize) -> BoxFuture<'_, ()>;
fn cancelled(&self) -> BoxFuture<'_, bool>;
fn resume(&self) -> Option<CrawlResume> {
None
}
fn tracks_frontier(&self) -> bool {
false
}
fn enqueued(&self, _urls: Vec<(String, usize)>) -> BoxFuture<'_, ()> {
Box::pin(async {})
}
fn summary(&self, _summary: CrawlSummary) -> BoxFuture<'_, ()> {
Box::pin(async {})
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct CrawlResume {
pub enqueued: Vec<String>,
pub pending: Vec<(String, usize)>,
pub done: usize,
}