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}