switchback_traits/traits/link.rs
1//! Intra-link extraction and formatting.
2
3use crate::error::Result;
4use crate::link_context::LinkContext;
5use crate::traits::contract::Entity;
6use crate::traits::contract_family::ContractFamily;
7use crate::traits::entity_category::EntityCategory;
8use crate::{IntraLink, LinkTarget, ResolvedManual};
9
10/// Extract intra-links from entity prose (sync, in-memory resolution).
11///
12/// Family parser crates implement this trait. Extraction may produce
13/// [`LinkTarget::Unresolved`] for unknown targets; strip those before wire serialize.
14pub trait LinkExtractor: Send + Sync {
15 /// Contract family this extractor belongs to.
16 type Family: ContractFamily;
17
18 /// Short extractor name (e.g. `"protobuf-fqn"`).
19 fn name(&self) -> &'static str;
20
21 /// Extracts prose-level links from `entity` against the `manual` address space.
22 fn extract<C: EntityCategory>(
23 &self,
24 entity: &Entity<C>,
25 manual: &ResolvedManual,
26 ) -> Vec<IntraLink>;
27}
28
29/// Extract intra-links with async cross-manual or remote resolution.
30///
31/// Use when link targets require network I/O or external manual fetches.
32pub trait AsyncLinkExtractor: Send + Sync {
33 /// Contract family this extractor belongs to.
34 type Family: ContractFamily;
35
36 /// Extracts prose-level links, resolving remote or cross-manual targets asynchronously.
37 async fn extract<C: EntityCategory>(
38 &self,
39 entity: &Entity<C>,
40 manual: &ResolvedManual,
41 ) -> Result<Vec<IntraLink>>;
42}
43
44/// Format a resolved link target for one output format (sync, no I/O).
45///
46/// Renderer crates implement this to turn [`LinkTarget`] values into markdown links,
47/// using [`LinkContext`] for relative path resolution.
48pub trait LinkFormatter: Send + Sync {
49 /// Short formatter name (e.g. `"markdown-relative"`).
50 fn name(&self) -> &'static str;
51
52 /// Formats `target` as a link string appropriate for the output format.
53 fn format(&self, target: &LinkTarget, ctx: &LinkContext) -> String;
54}