cartulary 0.3.0-alpha.1

The knowledge layer of your project — decisions, issues, docs, all in one place.
Documentation
//! Terminal `LinkResolver`: drops the scheme and keeps the bracket
//! text, with a self-bootstrapping suffix for `concept://` links —
//! the reader sees `Issue (cartu man issue)` so they can pivot
//! straight to the linked concept doc without leaving the terminal.
//!
//! Other schemes (`adr://`, `ddr://`, `issue://`) currently render
//! as bracket text only; pairing them with `cartu adr show <id>` etc.
//! requires knowing the configured decision kinds, deferred until a
//! concept doc actually uses them.

use crate::domain::usecases::doc::render::LinkResolver;

#[derive(Debug, Default)]
pub struct TerminalLinkResolver;

impl LinkResolver for TerminalLinkResolver {
    fn render_link(&self, text: &str, scheme: &str, target: &str) -> String {
        match scheme {
            "concept" => format!("{text} (cartu man {target})"),
            _ => text.to_string(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn concept_links_carry_the_pivot_command() {
        let r = TerminalLinkResolver;
        assert_eq!(
            r.render_link("Issue", "concept", "issue"),
            "Issue (cartu man issue)"
        );
        assert_eq!(
            r.render_link("status", "concept", "status"),
            "status (cartu man status)"
        );
    }

    #[test]
    fn other_typed_schemes_keep_only_the_bracket_text() {
        let r = TerminalLinkResolver;
        assert_eq!(r.render_link("ADR-0017", "adr", "0017"), "ADR-0017");
        assert_eq!(r.render_link("ISSUE-42", "issue", "42"), "ISSUE-42");
    }

    #[test]
    fn unknown_scheme_keeps_only_the_bracket_text() {
        let r = TerminalLinkResolver;
        assert_eq!(r.render_link("here", "https", "//example.com"), "here");
    }
}