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}