Skip to main content

dais_document/
source.rs

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