ic_query/ic/api_boundary_node/
text.rs1use super::IcApiBoundaryNodeReport;
8use crate::{
9 table::{ColumnAlign, render_table},
10 text_value::sanitize_text,
11};
12
13#[must_use]
15pub fn ic_api_boundary_node_report_text(report: &IcApiBoundaryNodeReport) -> String {
16 let provenance = &report.provenance;
17 let mut lines = vec![
18 format!("schema_version: {}", provenance.schema_version),
19 format!("network: {}", sanitize_text(&provenance.network)),
20 format!("authority: {}", sanitize_text(&provenance.authority)),
21 format!(
22 "source_endpoint: {}",
23 sanitize_text(&provenance.source_endpoint)
24 ),
25 format!(
26 "effective_canister_id: {}",
27 sanitize_text(&provenance.effective_canister_id)
28 ),
29 format!(
30 "fetched_at_unix_seconds: {}",
31 provenance.fetched_at_unix_seconds
32 ),
33 format!("fetched_at: {}", sanitize_text(&provenance.fetched_at)),
34 format!("fetched_by: {}", sanitize_text(&provenance.fetched_by)),
35 format!(
36 "certificate_time_unix_seconds: {}",
37 provenance.certificate_time_unix_seconds
38 ),
39 format!(
40 "certificate_time: {}",
41 sanitize_text(&provenance.certificate_time)
42 ),
43 format!("certified: {}", yes_no(provenance.certified)),
44 format!(
45 "point_in_time_guaranteed: {}",
46 yes_no(provenance.point_in_time_guaranteed)
47 ),
48 format!("node_count: {}", report.node_count),
49 ];
50
51 if !report.rows.is_empty() {
52 let rows = report
53 .rows
54 .iter()
55 .map(|row| {
56 [
57 row.node_id.clone(),
58 row.domain.clone(),
59 row.ipv4_address.clone().unwrap_or_else(|| "-".to_string()),
60 row.ipv6_address.clone(),
61 ]
62 })
63 .collect::<Vec<_>>();
64 lines.push(String::new());
65 lines.push("api_boundary_nodes:".to_string());
66 lines.push(render_table(
67 &["NODE ID", "DOMAIN", "IPV4", "IPV6"],
68 &rows,
69 &[
70 ColumnAlign::Left,
71 ColumnAlign::Left,
72 ColumnAlign::Left,
73 ColumnAlign::Left,
74 ],
75 ));
76 }
77
78 lines.join("\n")
79}
80
81const fn yes_no(value: bool) -> &'static str {
82 if value { "yes" } else { "no" }
83}