use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum PageProgressionDirection {
#[default]
Ltr,
Rtl,
Default,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Metadata {
pub title: String,
pub creators: Vec<String>,
pub publishers: Vec<String>,
pub languages: Vec<String>,
pub rights: Option<String>,
pub description: Option<String>,
pub identifier: Option<String>,
pub pub_date: Option<String>,
pub modified_date: Option<String>,
pub subjects: Vec<String>,
pub cover_id: Option<String>,
pub cover_href: Option<String>,
pub direction: PageProgressionDirection,
pub meta_properties: HashMap<String, String>,
pub accessibility: AccessibilityMetadata,
}
impl Metadata {
pub fn creator(&self) -> &str {
self.creators.first().map(|s| s.as_str()).unwrap_or("")
}
pub fn publisher(&self) -> Option<&str> {
self.publishers.first().map(|s| s.as_str())
}
pub fn language(&self) -> &str {
self.languages.first().map(|s| s.as_str()).unwrap_or("")
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct AccessibilityMetadata {
pub access_modes: Vec<String>,
pub access_modes_sufficient: Vec<Vec<String>>,
pub accessibility_features: Vec<String>,
pub accessibility_hazards: Vec<String>,
pub accessibility_summary: Option<String>,
pub certified_by: Option<String>,
pub certifier_credential: Option<String>,
pub certifier_report: Option<String>,
pub is_accessible: bool,
}
impl AccessibilityMetadata {
pub fn has_alternative_text(&self) -> bool {
self.accessibility_features
.iter()
.any(|f| f.contains("alternativeText"))
}
pub fn has_structural_navigation(&self) -> bool {
self.accessibility_features
.iter()
.any(|f| f.contains("structuralNavigation") || f.contains("tableOfContents"))
}
pub fn is_screen_reader_friendly(&self) -> bool {
self.access_modes.iter().any(|m| m == "textual") && self.has_structural_navigation()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManifestItem {
pub id: String,
pub href: String,
pub full_path: String,
pub media_type: String,
pub properties: Vec<String>,
pub fallback: Option<String>,
pub media_overlay: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpineItem {
pub idref: String,
pub linear: bool,
pub properties: Vec<String>,
pub index: usize,
pub href: String,
pub media_type: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GuideItem {
pub type_: String,
pub title: String,
pub href: String,
pub full_path: String,
}