use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(Debug, Clone, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
pub struct ScrapeRequest {
#[serde(default)]
#[schema(example = "https://example.com")]
pub url: String,
#[serde(default)]
#[schema(example = json!(["markdown"]))]
pub formats: Option<Vec<String>>,
#[serde(default)]
pub only_main_content: Option<bool>,
#[serde(default)]
pub include_tags: Option<Vec<String>>,
#[serde(default)]
pub exclude_tags: Option<Vec<String>>,
#[serde(default)]
#[schema(example = 30000)]
pub timeout: Option<u64>,
}
#[derive(Debug, Clone, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct CrawlRequest {
#[serde(default)]
#[schema(example = "https://example.com")]
pub url: String,
#[serde(default)]
#[schema(example = 2)]
pub max_depth: Option<usize>,
#[serde(default)]
#[schema(example = 100)]
pub max_pages: Option<usize>,
#[serde(default)]
pub include_paths: Option<Vec<String>>,
#[serde(default)]
pub exclude_paths: Option<Vec<String>>,
#[serde(default)]
pub only_main_content: Option<bool>,
}
#[derive(Debug, Clone, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct MapRequest {
#[serde(default)]
#[schema(example = "https://example.com")]
pub url: String,
#[serde(default)]
#[schema(example = 100)]
pub limit: Option<usize>,
#[serde(default)]
pub search: Option<String>,
}
#[derive(Debug, Clone, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
pub struct BatchScrapeRequest {
#[schema(example = json!(["https://example.com", "https://example.org"]))]
pub urls: Vec<String>,
#[serde(default)]
pub formats: Option<Vec<String>>,
#[serde(default)]
pub only_main_content: Option<bool>,
}
#[derive(Debug, Clone, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
pub struct DownloadRequest {
#[serde(default)]
#[schema(example = "https://example.com/document.pdf")]
pub url: String,
#[serde(default)]
pub max_size: Option<usize>,
}
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct ErrorBody {
#[schema(example = "BAD_REQUEST")]
pub code: &'static str,
#[schema(example = "url is required")]
pub message: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct ApiResponse<T: Serialize> {
pub success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<T>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<ErrorBody>,
}
impl<T: Serialize> ApiResponse<T> {
pub fn ok(data: T) -> Self {
Self {
success: true,
data: Some(data),
error: None,
}
}
}
impl ApiResponse<()> {
pub fn err(code: &'static str, message: impl Into<String>) -> Self {
Self {
success: false,
data: None,
error: Some(ErrorBody {
code,
message: message.into(),
}),
}
}
}
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct JobCreatedResponse {
#[schema(example = true)]
pub success: bool,
#[schema(example = "550e8400-e29b-41d4-a716-446655440000")]
pub id: String,
}
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct JobStatusResponse {
#[schema(example = "completed")]
pub status: String,
#[schema(example = 10)]
pub total: usize,
#[schema(example = 10)]
pub completed: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Vec<serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct HealthResponse {
#[schema(example = "ok")]
pub status: &'static str,
#[schema(example = "0.1.0")]
pub version: &'static str,
}
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct VersionResponse {
#[schema(example = "0.1.0")]
pub version: &'static str,
}