use serde::{Deserialize, Deserializer, Serialize};
use crate::check::CheckId;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct InlinkSample {
pub target: u32,
pub source: u32,
pub anchor: String,
pub nofollow: bool,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct StatusCounts {
pub ok: u32,
pub redirect: u32,
pub client_error: u32,
pub server_error: u32,
pub failed: u32,
pub blocked: u32,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CrawlSummary {
pub pages: u32,
pub indexable: u32,
pub status: StatusCounts,
pub depth: Vec<u32>,
pub no_depth: u32,
pub avg_response_ms: u32,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CrawlReport {
pub health_score: u8,
pub checks_passed: u16,
pub checks_total: u16,
#[serde(deserialize_with = "known_counts")]
pub counts: Vec<(CheckId, u32)>,
pub inlink_samples: Vec<InlinkSample>,
pub summary: CrawlSummary,
}
fn known_counts<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<(CheckId, u32)>, D::Error> {
let raw = Vec::<(String, u32)>::deserialize(d)?;
Ok(raw
.into_iter()
.filter_map(|(slug, n)| Some((CheckId::from_slug(&slug)?, n)))
.collect())
}