Skip to main content

devscout_rs/render/
read.rs

1use crate::query;
2
3use super::refs::{render_refs_compact, render_refs_text};
4
5// The `def:` line both `read` renderers open with: the declaring sites in
6// refs' own order, with the PRIMARY site carrying the recorded span
7// (`file:start-end`) when one is on record. A site without a span fact
8// prints start-only -- an absent end is never rendered as a range. When the
9// model carries a source block it goes under this line, verbatim.
10fn read_def_line(model: &query::ReadModel) -> String {
11    let sites = &model.refs.sites;
12    if sites.is_empty() {
13        return "def: -".to_string();
14    }
15    let rendered: Vec<String> = sites
16        .iter()
17        .enumerate()
18        .map(|(i, s)| match (i, &model.span) {
19            (0, Some(sp)) => format!("{}:{}-{}", sp.file, sp.start_line, sp.end_line),
20            _ => format!("{}:{}", s.file, s.line),
21        })
22        .collect();
23    format!("def: {}", rendered.join("  "))
24}
25
26/// Default (non-compact) `read` rendering: the declaration span and its
27///
28/// verbatim source, then exactly the inbound answer `refs` gives -- same
29/// tables, same cap trailer, same ambiguous section and manifest-gap note.
30pub fn render_read_text(model: &query::ReadModel) -> String {
31    let rendered = render_refs_text(&model.refs);
32    let mut out: Vec<String> = rendered.split('\n').map(str::to_string).collect();
33    if out.len() > 1 {
34        out[1] = read_def_line(model);
35    }
36    if let Some(sp) = &model.span {
37        out.splice(2..2, sp.source.split('\n').map(str::to_string));
38    }
39    out.join("\n")
40}
41
42/// `--compact` `read` rendering: the span on the def line, no source block,
43///
44/// then the compact inbound blocks and summary. Everything `refs --compact`
45/// prints minus the outbound side, which `read` never computes.
46pub fn render_read_compact(model: &query::ReadModel) -> String {
47    let rendered = render_refs_compact(&model.refs);
48    let mut out: Vec<String> = rendered.split('\n').map(str::to_string).collect();
49    if out.len() > 1 {
50        out[1] = read_def_line(model);
51    }
52    out.join("\n")
53}