Skip to main content

dais_document/
source.rs

1use crate::page::{PageDimensions, RenderSize, RenderedPage};
2
3/// Abstraction over document sources.
4///
5/// Implementations provide page geometry, rendering, embedded metadata, and
6/// outline data without exposing renderer-specific details to the engine or UI.
7pub trait DocumentSource: Send + Sync {
8    /// Total number of pages in the document.
9    fn page_count(&self) -> usize;
10
11    /// Dimensions of a specific page (in points).
12    fn page_dimensions(&self, page_index: usize) -> PageDimensions;
13
14    /// Render a page to an RGBA bitmap at the specified target size.
15    fn render_page(
16        &self,
17        page_index: usize,
18        target_size: RenderSize,
19    ) -> Result<RenderedPage, DocumentError>;
20
21    /// Extract embedded metadata (pdfpc-compatible), if present.
22    fn embedded_metadata(&self) -> Option<EmbeddedMetadata>;
23
24    /// PDF outline/bookmark entries, if present.
25    fn outline(&self) -> Option<Vec<OutlineEntry>>;
26}
27
28/// Metadata embedded in the PDF by `Polylux`/touying/pdfpc LaTeX package.
29#[derive(Debug, Clone)]
30pub struct EmbeddedMetadata {
31    /// Raw pdfpc metadata string from the PDF info dictionary.
32    pub pdfpc_data: Option<String>,
33}
34
35/// A bookmark/outline entry in the document.
36#[derive(Debug, Clone)]
37pub struct OutlineEntry {
38    /// Bookmark title as displayed by the document.
39    pub title: String,
40    /// Destination page index, 0-based.
41    pub page_index: usize,
42    /// Nesting depth in the outline tree, starting at 0.
43    pub level: usize,
44}
45
46/// Errors from document operations.
47#[derive(Debug, thiserror::Error)]
48pub enum DocumentError {
49    /// The document could not be opened or parsed.
50    #[error("Failed to open document: {0}")]
51    Open(String),
52
53    /// A page render failed after the document was opened successfully.
54    #[error("Failed to render page {page_index}: {message}")]
55    Render { page_index: usize, message: String },
56
57    /// The requested page index is outside the document.
58    #[error("Page index {0} out of range")]
59    PageOutOfRange(usize),
60
61    /// An underlying filesystem operation failed.
62    #[error("I/O error: {0}")]
63    Io(#[from] std::io::Error),
64}