Skip to content

Commit ff546dc

Browse files
authored
[fm] factor out fmt_json_value into its own module (#10511)
`nexus_types::fm` has a little utility for formatting `serde_json::Value`s as bulleted lists. Currently, this is only used for formatting sitrep analysis reports. #10460 factored it out of the `analysis_reports` module to use it for formatting case facts. While working on #10505, I realized it would also be useful to have this for use in `omdb` commands for reconstructing analysis reports from CRDB. Since #10460 isn't going to merge until after R20, I figured it would be helpful to just pull out the change to factor this out into its own commit that both our branches could depend on.
1 parent acbe5e6 commit ff546dc

3 files changed

Lines changed: 89 additions & 79 deletions

File tree

nexus/types/src/fm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub mod ereport;
1212
pub use ereport::{Ereport, EreportId};
1313
pub mod case;
1414
pub use case::Case;
15+
pub(crate) mod json_display;
1516

1617
use case::AlertRequest;
1718
use chrono::{DateTime, Utc};

nexus/types/src/fm/analysis_reports.rs

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
88
use super::case;
99
use super::ereport::EreportId;
10+
use super::json_display::fmt_json_value;
1011
use iddqd::IdOrdMap;
1112
use omicron_uuid_kinds::{CaseUuid, CollectionUuid, SitrepUuid};
1213
use serde::{Deserialize, Serialize};
@@ -158,85 +159,6 @@ impl DebugLog {
158159
}
159160
}
160161

161-
/// Recursively format a JSON value as a bulleted list entry, nesting any
162-
/// object or array children as indented sub-bullets.
163-
fn fmt_json_value(
164-
f: &mut fmt::Formatter<'_>,
165-
key: &str,
166-
value: &serde_json::Value,
167-
indent: usize,
168-
) -> fmt::Result {
169-
match value {
170-
serde_json::Value::Object(map) => {
171-
writeln!(f, "{:indent$}* {key}:", "")?;
172-
for (k, v) in map {
173-
fmt_json_value(f, k, v, indent + 2)?;
174-
}
175-
Ok(())
176-
}
177-
serde_json::Value::Array(arr) => {
178-
writeln!(f, "{:indent$}* {key}:", "")?;
179-
let indent = indent + 2;
180-
for (i, v) in arr.iter().enumerate() {
181-
fmt_json_array_item(f, i + 1, v, indent)?;
182-
}
183-
Ok(())
184-
}
185-
serde_json::Value::String(s) => {
186-
writeln!(f, "{:indent$}* {key}: {s}", "")
187-
}
188-
serde_json::Value::Null => {
189-
writeln!(f, "{:indent$}* {key}: <none>", "")
190-
}
191-
serde_json::Value::Bool(b) => {
192-
writeln!(f, "{:indent$}* {key}: {b}", "")
193-
}
194-
serde_json::Value::Number(n) => {
195-
writeln!(f, "{:indent$}* {key}: {n}", "")
196-
}
197-
}
198-
}
199-
200-
/// Format a single element of a JSON array as a numbered list item,
201-
/// e.g. `1. value` for scalars or `1.` followed by indented children for
202-
/// objects and nested arrays.
203-
fn fmt_json_array_item(
204-
f: &mut fmt::Formatter<'_>,
205-
n: usize,
206-
value: &serde_json::Value,
207-
indent: usize,
208-
) -> fmt::Result {
209-
match value {
210-
serde_json::Value::Object(map) => {
211-
writeln!(f, "{:indent$}{n}.", "")?;
212-
for (k, v) in map {
213-
fmt_json_value(f, k, v, indent + 2)?;
214-
}
215-
Ok(())
216-
}
217-
serde_json::Value::Array(arr) => {
218-
writeln!(f, "{:indent$}{n}.", "")?;
219-
let indent = indent + 2;
220-
for (i, v) in arr.iter().enumerate() {
221-
fmt_json_array_item(f, i + 1, v, indent)?;
222-
}
223-
Ok(())
224-
}
225-
serde_json::Value::String(s) => {
226-
writeln!(f, "{:indent$}{n}. {s}", "")
227-
}
228-
serde_json::Value::Null => {
229-
writeln!(f, "{:indent$}{n}. <none>", "")
230-
}
231-
serde_json::Value::Bool(b) => {
232-
writeln!(f, "{:indent$}{n}. {b}", "")
233-
}
234-
serde_json::Value::Number(num) => {
235-
writeln!(f, "{:indent$}{n}. {num}", "")
236-
}
237-
}
238-
}
239-
240162
impl LogEntry {
241163
pub fn new(event: impl ToString) -> Self {
242164
Self { event: event.to_string(), comment: None, kvs: BTreeMap::new() }

nexus/types/src/fm/json_display.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
//! Shared helpers for rendering `serde_json::Value`s as bulleted lists in
6+
//! `Display` impls.
7+
8+
use std::fmt;
9+
10+
/// Recursively format a JSON value as a bulleted list entry, nesting any
11+
/// object or array children as indented sub-bullets.
12+
pub(crate) fn fmt_json_value(
13+
f: &mut fmt::Formatter<'_>,
14+
key: &str,
15+
value: &serde_json::Value,
16+
indent: usize,
17+
) -> fmt::Result {
18+
match value {
19+
serde_json::Value::Object(map) => {
20+
writeln!(f, "{:indent$}* {key}:", "")?;
21+
for (k, v) in map {
22+
fmt_json_value(f, k, v, indent + 2)?;
23+
}
24+
Ok(())
25+
}
26+
serde_json::Value::Array(arr) => {
27+
writeln!(f, "{:indent$}* {key}:", "")?;
28+
let indent = indent + 2;
29+
for (i, v) in arr.iter().enumerate() {
30+
fmt_json_array_item(f, i + 1, v, indent)?;
31+
}
32+
Ok(())
33+
}
34+
serde_json::Value::String(s) => {
35+
writeln!(f, "{:indent$}* {key}: {s}", "")
36+
}
37+
serde_json::Value::Null => {
38+
writeln!(f, "{:indent$}* {key}: <none>", "")
39+
}
40+
serde_json::Value::Bool(b) => {
41+
writeln!(f, "{:indent$}* {key}: {b}", "")
42+
}
43+
serde_json::Value::Number(n) => {
44+
writeln!(f, "{:indent$}* {key}: {n}", "")
45+
}
46+
}
47+
}
48+
49+
/// Format a single element of a JSON array as a numbered list item,
50+
/// e.g. `1. value` for scalars or `1.` followed by indented children for
51+
/// objects and nested arrays.
52+
pub(crate) fn fmt_json_array_item(
53+
f: &mut fmt::Formatter<'_>,
54+
n: usize,
55+
value: &serde_json::Value,
56+
indent: usize,
57+
) -> fmt::Result {
58+
match value {
59+
serde_json::Value::Object(map) => {
60+
writeln!(f, "{:indent$}{n}.", "")?;
61+
for (k, v) in map {
62+
fmt_json_value(f, k, v, indent + 2)?;
63+
}
64+
Ok(())
65+
}
66+
serde_json::Value::Array(arr) => {
67+
writeln!(f, "{:indent$}{n}.", "")?;
68+
let indent = indent + 2;
69+
for (i, v) in arr.iter().enumerate() {
70+
fmt_json_array_item(f, i + 1, v, indent)?;
71+
}
72+
Ok(())
73+
}
74+
serde_json::Value::String(s) => {
75+
writeln!(f, "{:indent$}{n}. {s}", "")
76+
}
77+
serde_json::Value::Null => {
78+
writeln!(f, "{:indent$}{n}. <none>", "")
79+
}
80+
serde_json::Value::Bool(b) => {
81+
writeln!(f, "{:indent$}{n}. {b}", "")
82+
}
83+
serde_json::Value::Number(num) => {
84+
writeln!(f, "{:indent$}{n}. {num}", "")
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)