layout_audit/output/
json.rs1use crate::types::StructLayout;
2use serde::Serialize;
3
4#[derive(Serialize)]
5struct Output<'a> {
6 version: &'static str,
7 structs: &'a [StructLayout],
8}
9
10pub struct JsonFormatter {
11 pretty: bool,
12}
13
14impl JsonFormatter {
15 pub fn new(pretty: bool) -> Self {
16 Self { pretty }
17 }
18
19 pub fn format(&self, layouts: &[StructLayout]) -> String {
20 let output = Output { version: env!("CARGO_PKG_VERSION"), structs: layouts };
21
22 if self.pretty {
23 serde_json::to_string_pretty(&output)
24 .unwrap_or_else(|e| format!("{{\"error\": \"{}\"}}", e))
25 } else {
26 serde_json::to_string(&output).unwrap_or_else(|e| format!("{{\"error\": \"{}\"}}", e))
27 }
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::types::{LayoutMetrics, StructLayout};
35
36 fn layout(name: &str) -> StructLayout {
37 let mut s = StructLayout::new(name.to_string(), 8, Some(8));
38 s.metrics = LayoutMetrics { padding_bytes: 0, total_size: 8, ..LayoutMetrics::default() };
39 s
40 }
41
42 #[test]
43 fn json_formatter_pretty() {
44 let formatter = JsonFormatter::new(true);
45 let out = formatter.format(&[layout("Foo")]);
46 let parsed: serde_json::Value = serde_json::from_str(&out).expect("valid JSON");
47 assert!(parsed["structs"].is_array());
48 }
49
50 #[test]
51 fn json_formatter_compact() {
52 let formatter = JsonFormatter::new(false);
53 let out = formatter.format(&[layout("Foo")]);
54 assert!(out.contains("\"structs\""));
55 }
56}