Skip to main content

rto_render/
lib.rs

1//! Renderers over the Roteiro graph. All outputs — docs site, Obsidian vault,
2//! and the optional MCP server (feature `mcp`) — are build products of the
3//! same store, so humans and agents always see the same data.
4
5mod docs;
6mod obsidian;
7
8#[cfg(feature = "mcp")]
9pub mod mcp;
10
11pub use docs::{IndexEntry, RenderedAdr, markdown_to_html, render_adr, render_adr_index};
12pub use obsidian::{VaultNote, note_name, render_note};
13
14/// A render target for the graph.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum Target {
17    /// Static documentation website (ADRs, blueprints, AI context pages).
18    DocsSite,
19    /// Obsidian-compatible markdown vault.
20    ObsidianVault,
21}
22
23impl Target {
24    /// Stable CLI name for this target.
25    #[must_use]
26    pub fn as_str(self) -> &'static str {
27        match self {
28            Self::DocsSite => "docs",
29            Self::ObsidianVault => "obsidian",
30        }
31    }
32
33    /// Parse a target from its CLI name.
34    #[must_use]
35    pub fn parse(s: &str) -> Option<Self> {
36        match s {
37            "docs" => Some(Self::DocsSite),
38            "obsidian" => Some(Self::ObsidianVault),
39            _ => None,
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::Target;
47
48    #[test]
49    fn target_names_are_stable() {
50        assert_eq!(Target::DocsSite.as_str(), "docs");
51        assert_eq!(Target::ObsidianVault.as_str(), "obsidian");
52        assert_eq!(Target::parse("docs"), Some(Target::DocsSite));
53        assert_eq!(Target::parse("obsidian"), Some(Target::ObsidianVault));
54        assert_eq!(Target::parse("nope"), None);
55    }
56}