Skip to main content

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}