simple_gal/types.rs
1//! Shared types used across all pipeline stages.
2//!
3//! These types are serialized to JSON between stages (scan → process → generate)
4//! and must be identical across all three modules.
5
6use serde::{Deserialize, Serialize};
7
8/// A page generated from a markdown file in the content root.
9///
10/// Pages follow the same numbering convention as albums:
11/// - Numbered files (`NNN-name.md`) appear in navigation, sorted by number
12/// - Unnumbered files are generated but hidden from navigation
13///
14/// If the file content is just a URL, the page becomes an external link in nav.
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct Page {
17 /// Title from first `# heading` in markdown, or link_title as fallback
18 pub title: String,
19 /// Display label in nav (filename with number stripped and dashes → spaces)
20 pub link_title: String,
21 /// URL slug (filename stem with number prefix stripped)
22 pub slug: String,
23 /// Raw markdown content (or URL for link pages)
24 pub body: String,
25 /// Whether this page appears in navigation (has number prefix)
26 pub in_nav: bool,
27 /// Sort key from number prefix (for ordering)
28 pub sort_key: u32,
29 /// If true, body is a URL and this page is an external link
30 pub is_link: bool,
31}
32
33/// Navigation tree item (only numbered directories).
34///
35/// Leaf items (no children) correspond to albums. Items with children are
36/// container directories (groups) that generate gallery-list pages. Container
37/// items can carry an optional `description` read from `description.md`/`.txt`
38/// in the container directory.
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct NavItem {
41 pub title: String,
42 pub path: String,
43 #[serde(default, skip_serializing_if = "String::is_empty")]
44 pub source_dir: String,
45 /// Optional description for container directories, rendered on their gallery-list page.
46 #[serde(default, skip_serializing_if = "Option::is_none")]
47 pub description: Option<String>,
48 #[serde(default, skip_serializing_if = "Vec::is_empty")]
49 pub children: Vec<NavItem>,
50}