tiger_lib/report/
writer_json.rs

1use std::io::Write;
2
3use serde_json::json;
4
5use crate::fileset::FileStage;
6use crate::report::errors::Errors;
7use crate::report::writer::kind_tag;
8use crate::report::{LogReportMetadata, LogReportPointers};
9
10/// Log the report in JSON format.
11pub fn log_report_json<O: Write + Send>(
12    errors: &Errors,
13    output: &mut O,
14    report: &LogReportMetadata,
15    pointers: &LogReportPointers,
16) {
17    let pointers: Vec<_> = pointers
18        .iter()
19        .map(|pointer| {
20            let path = pointer.loc.pathname();
21            let fullpath = pointer.loc.fullpath();
22            json!({
23                "path": path,
24                "from": kind_tag(errors, pointer.loc.kind),
25                "stage": stage_desc(pointer.loc.stage),
26                "fullpath": fullpath,
27                "linenr": if pointer.loc.line == 0 { None } else { Some(pointer.loc.line) },
28                "column": if pointer.loc.column == 0 { None } else { Some(pointer.loc.column) },
29                "length": if pointer.length == 0 { None } else { Some(pointer.length) },
30                "line": errors.cache.get_line(pointer.loc),
31                "tag": pointer.msg,
32            })
33        })
34        .collect();
35    let report = json!({
36        "severity": report.severity,
37        "confidence": report.confidence,
38        "key": report.key,
39        "message": &report.msg,
40        "info": &report.info,
41        "wiki": &report.wiki,
42        "locations": pointers,
43    });
44
45    if let Err(e) = serde_json::to_writer_pretty(output, &report) {
46        eprintln!("JSON error: {e:#}");
47    }
48}
49
50fn stage_desc(stage: FileStage) -> Option<&'static str> {
51    match stage {
52        #[cfg(feature = "eu5")]
53        FileStage::LoadingScreen => Some("loading_screen"),
54        #[cfg(feature = "eu5")]
55        FileStage::MainMenu => Some("main_menu"),
56        #[cfg(feature = "eu5")]
57        FileStage::InGame => Some("in_game"),
58        FileStage::NoStage => None,
59    }
60}