use std::{fs::File, io::Write};
use glua_code_analysis::{DbIndex, FileId};
use lsp_types::Diagnostic;
use serde_json::{Value, json};
use crate::cmd_args::OutputDestination;
use super::OutputWriter;
#[derive(Debug)]
pub struct JsonOutputWriter {
output: Option<File>,
first_write: bool,
json_file_caches: Vec<Value>,
}
impl JsonOutputWriter {
pub fn new(output: OutputDestination) -> Self {
let output = match output {
OutputDestination::Stdout => None,
OutputDestination::File(path) => {
if let Some(parent) = path.parent()
&& !parent.exists()
{
std::fs::create_dir_all(parent).unwrap();
}
Some(std::fs::File::create(path).unwrap())
}
};
JsonOutputWriter {
output,
first_write: true,
json_file_caches: Vec::new(),
}
}
}
impl OutputWriter for JsonOutputWriter {
fn write(&mut self, db: &DbIndex, file_id: FileId, diagnostics: Vec<Diagnostic>) {
let file_path = db.get_vfs().get_file_path(&file_id).unwrap();
let file_path = file_path.to_str().unwrap();
let mut json_diagnostics = Vec::new();
for diagnostic in diagnostics {
let json_diagnostic = serde_json::to_value(diagnostic).unwrap();
json_diagnostics.push(json_diagnostic);
}
let json_file = json!({
"file": file_path,
"diagnostics": json_diagnostics,
});
if self.output.is_none() {
if self.first_write {
self.first_write = false;
println!("[");
} else {
println!(",");
}
println!("{}", serde_json::to_string_pretty(&json_file).unwrap());
} else {
self.json_file_caches.push(json_file);
}
}
fn finish(&mut self) {
if let Some(output) = self.output.as_mut() {
let pretty_json = serde_json::to_string_pretty(&self.json_file_caches).unwrap();
output.write_all(pretty_json.as_bytes()).unwrap();
} else if !self.first_write {
println!("\n]");
}
}
}