Skip to main content

mant_ir/
address.rs

1//! Stable logical identities for documents independent from storage paths.
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6/// Storage identity of one registered Markdown document.
7#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema)]
8#[serde(
9    tag = "kind",
10    rename_all = "kebab-case",
11    rename_all_fields = "camelCase"
12)]
13pub enum MarkdownOrigin {
14    /// The user's primary `documents` tree.
15    Documents,
16    /// A configured source cache.
17    Source {
18        /// Configured source name.
19        name: String,
20    },
21}
22
23/// Stable selector for one discoverable document candidate.
24#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema)]
25#[serde(
26    tag = "kind",
27    rename_all = "kebab-case",
28    rename_all_fields = "camelCase"
29)]
30pub enum DocumentAddress {
31    /// A Markdown document registered in the document catalog.
32    Markdown {
33        /// Extension-free path relative to the selected Markdown origin.
34        path: String,
35        /// Storage namespace containing the relative path.
36        origin: MarkdownOrigin,
37    },
38    /// An installed native manual page.
39    Manual {
40        /// Manual topic without its section suffix.
41        name: String,
42        /// Native manual category such as `1` or `3p`.
43        manual_section: String,
44    },
45}
46
47impl DocumentAddress {
48    /// Return the basename used as the document's short lookup name.
49    #[must_use]
50    pub fn name(&self) -> &str {
51        match self {
52            Self::Markdown { path, .. } => path.rsplit('/').next().unwrap_or(path),
53            Self::Manual { name, .. } => name,
54        }
55    }
56
57    /// Stable path relative to its storage namespace.
58    #[must_use]
59    pub fn relative_path(&self) -> String {
60        match self {
61            Self::Markdown { path, .. } => path.clone(),
62            Self::Manual {
63                name,
64                manual_section,
65            } => format!("{manual_section}/{name}"),
66        }
67    }
68
69    /// Complete, unambiguous path in `ManT`'s unified document tree.
70    #[must_use]
71    pub fn catalog_path(&self) -> String {
72        match self {
73            Self::Markdown {
74                path,
75                origin: MarkdownOrigin::Documents,
76            } => format!("documents/{path}"),
77            Self::Markdown {
78                path,
79                origin: MarkdownOrigin::Source { name },
80            } => format!("sources/{name}/{path}"),
81            Self::Manual {
82                name,
83                manual_section,
84            } => format!("manual/{manual_section}/{name}"),
85        }
86    }
87}