docgen_core/model.rs
1use serde::Serialize;
2
3/// A discovered markdown file, before processing.
4#[derive(Debug, Clone, PartialEq)]
5pub struct RawDoc {
6 /// Path relative to the docs root, using `/` separators, e.g. `guide/intro.md`.
7 pub rel_path: String,
8 /// Raw file contents.
9 pub raw: String,
10}
11
12/// A fully processed document ready to render.
13#[derive(Debug, Clone, PartialEq, Serialize)]
14pub struct Doc {
15 /// Path relative to docs root, e.g. `guide/intro.md`.
16 pub rel_path: String,
17 /// URL slug without extension, e.g. `guide/intro`.
18 pub slug: String,
19 /// Resolved page title.
20 pub title: String,
21 /// Frontmatter `description:`, if any. Feeds the home dashboard subtitle and
22 /// the "Recent" list. `None` when the doc has no `description:`.
23 #[serde(default, skip_serializing_if = "Option::is_none")]
24 pub description: Option<String>,
25 /// Rendered body HTML.
26 pub body_html: String,
27 /// Whether this doc contains math (drives the conditional KaTeX `<head>` link).
28 pub has_math: bool,
29 /// Whether this doc contains a mermaid diagram (drives the lazy island load).
30 pub has_mermaid: bool,
31 /// Names of custom components rendered on this page (drives per-page island load).
32 #[serde(default)]
33 pub components_used: std::collections::BTreeSet<String>,
34 /// The `h2`/`h3` outline of this page, in document order, for the right-rail
35 /// "On this page" table of contents. Ids match the `id` attributes stamped
36 /// onto the rendered heading tags in `body_html`.
37 #[serde(default)]
38 pub headings: Vec<crate::headings::Heading>,
39}
40
41/// A node in the sidebar tree.
42#[derive(Debug, Clone, PartialEq, Serialize)]
43#[serde(tag = "kind", rename_all = "lowercase")]
44pub enum TreeNode {
45 Dir {
46 name: String,
47 /// Slug of this folder's "folder note" — an `index.md` directly inside the
48 /// directory. `Some` makes the folder label a link to that page (clicking
49 /// the folder focuses its note); `None` is a plain, non-navigable group.
50 /// The note doc is NOT also emitted as a child of this dir.
51 #[serde(default, skip_serializing_if = "Option::is_none")]
52 slug: Option<String>,
53 children: Vec<TreeNode>,
54 },
55 Doc {
56 name: String,
57 slug: String,
58 title: String,
59 },
60}
61
62/// One resolved wikilink edge: `from` doc links to `to` doc (both slugs).
63#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize)]
64pub struct LinkEdge {
65 pub from: String,
66 pub to: String,
67}
68
69/// Per-target inbound reference, for rendering a "Backlinks" section.
70#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize)]
71pub struct Backlink {
72 pub slug: String,
73 pub title: String,
74 /// The linking doc's frontmatter description, rendered as a `<small>` under
75 /// the title in the rail's "Referenced by" cards. `None` when the linking
76 /// doc has no `description:` in its frontmatter.
77 #[serde(default, skip_serializing_if = "Option::is_none")]
78 pub description: Option<String>,
79}
80
81/// One entry in the static search index.
82#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
83pub struct SearchEntry {
84 pub slug: String,
85 pub title: String,
86 pub text: String,
87}