nichlink/registry_core/mir/
render.rs1use std::fmt::Write as _;
5
6use crate::json::json_string;
7
8use super::model::MirGraph;
9
10impl MirGraph {
11 pub fn render(&self) -> String {
15 let mut output = String::new();
16 writeln!(output, "MIR CANDIDATES").unwrap();
17 for call in &self.calls {
18 writeln!(
19 output,
20 " {} -> {} @ MIR line {}",
21 call.caller, call.callee, call.mir_line
22 )
23 .unwrap();
24 }
25 if self.calls.is_empty() {
26 output.push_str(" (no static call candidates)\n");
27 }
28 writeln!(output, "LOCALS").unwrap();
29 for local in &self.locals {
30 writeln!(
31 output,
32 " {}::{}: {} @ MIR line {}",
33 local.function, local.name, local.type_name, local.mir_line
34 )
35 .unwrap();
36 }
37 output
38 }
39
40 pub fn to_jsonl(&self) -> String {
52 let mut output = String::new();
53 for function in &self.functions {
54 writeln!(
55 output,
56 "{{\"kind\":\"function\",\"name\":{}}}",
57 json_string(function)
58 )
59 .unwrap();
60 }
61 for call in &self.calls {
62 writeln!(
63 output,
64 "{{\"kind\":\"call\",\"caller\":{},\"callee\":{},\"mir_line\":{}}}",
65 json_string(&call.caller),
66 json_string(&call.callee),
67 call.mir_line
68 )
69 .unwrap();
70 }
71 for local in &self.locals {
72 writeln!(
73 output,
74 "{{\"kind\":\"local\",\"function\":{},\"name\":{},\"type\":{},\"mir_line\":{}}}",
75 json_string(&local.function),
76 json_string(&local.name),
77 json_string(&local.type_name),
78 local.mir_line
79 )
80 .unwrap();
81 }
82 output
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::MirGraph;
89
90 #[test]
91 fn jsonl_artifact_round_trips() {
92 let graph = MirGraph::from_jsonl(
93 "{\"kind\":\"function\",\"name\":\"crate::a\"}\n{\"kind\":\"call\",\"caller\":\"crate::a\",\"callee\":\"crate::b\",\"mir_line\":3}\n",
94 )
95 .unwrap();
96 let parsed = MirGraph::from_jsonl(&graph.to_jsonl()).unwrap();
97 assert_eq!(parsed, graph);
98 }
99
100 #[test]
106 fn a_control_character_in_a_name_stays_escaped() {
107 let graph = MirGraph::from_jsonl(
108 "{\"kind\":\"function\",\"name\":\"a\\tb\"}\n{\"kind\":\"call\",\"caller\":\"a\\tb\",\"callee\":\"c\",\"mir_line\":1}\n",
109 )
110 .unwrap();
111 let jsonl = graph.to_jsonl();
112 for line in jsonl.lines() {
116 assert!(
117 !line.chars().any(|character| character < '\u{20}'),
118 "a raw control character makes the line invalid for a strict reader: {line:?}"
119 );
120 }
121 assert!(jsonl.contains(r#""name":"a\tb""#), "{jsonl:?}");
122 }
123}