use serde::{Deserialize, Serialize};
use std::sync::Arc;
use super::extraction::BoundingBox;
use super::serde_helpers::serde_vec_arc;
use super::tables::Table;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
pub struct PageStructure {
pub total_count: u32,
pub unit_type: PageUnitType,
#[serde(skip_serializing_if = "Option::is_none")]
pub boundaries: Option<Vec<PageBoundary>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pages: Option<Vec<PageInfo>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
pub enum PageUnitType {
Page,
Slide,
Sheet,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
pub struct PageBoundary {
pub byte_start: usize,
pub byte_end: usize,
pub page_number: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
pub struct PageInfo {
pub number: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(skip)]
#[cfg_attr(feature = "api", schema(value_type = Option<[f64; 2]>))]
#[cfg_attr(alef, alef(skip))]
pub dimensions: Option<(f64, f64)>,
#[serde(skip_serializing_if = "Option::is_none")]
pub image_count: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub table_count: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hidden: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_blank: Option<bool>,
#[serde(default, skip_serializing_if = "is_default_bool")]
pub has_vector_graphics: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
pub struct PageContent {
pub page_number: u32,
pub content: String,
#[serde(skip_serializing_if = "Vec::is_empty", default, with = "serde_vec_arc")]
#[cfg_attr(feature = "api", schema(value_type = Vec<Table>))]
pub tables: Vec<Arc<Table>>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub image_indices: Vec<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hierarchy: Option<PageHierarchy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_blank: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub layout_regions: Option<Vec<LayoutRegion>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub speaker_notes: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub section_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sheet_name: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
pub struct LayoutRegion {
#[serde(alias = "class")]
pub class_name: String,
pub confidence: f64,
pub bounding_box: BoundingBox,
pub area_fraction: f64,
}
impl LayoutRegion {
#[deprecated(since = "4.10.0", note = "Use `class_name` field instead")]
pub fn class(&self) -> &str {
&self.class_name
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
pub struct PageHierarchy {
pub block_count: u32,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub blocks: Vec<HierarchicalBlock>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
pub struct HierarchicalBlock {
pub text: String,
pub font_size: f32,
pub level: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "api", schema(value_type = Option<[f32; 4]>))]
#[cfg_attr(alef, alef(skip))]
pub bbox: Option<(f32, f32, f32, f32)>,
}
fn is_default_bool(v: &bool) -> bool {
!*v
}