use {
crate::{
Partitions,
TRACER,
database::PartitionKey,
partitions::Diagnostics,
protocol::{
jsonrpc,
lsp::{
LSPAny,
LanguageServer,
},
},
record::LaburnumRecordRef,
scheduler::task::TaskContext,
},
opentelemetry::trace::FutureExt,
serde_json::Value,
};
pub async fn handle_ariadne_diagnostics<
P: Partitions,
T: LanguageServer<P>,
>(
arguments: &[Value],
ctx: &mut TaskContext<P, T>,
) -> jsonrpc::Result<Option<LSPAny>> {
let arg = arguments.first();
let color = arg
.and_then(|a| a.get("color"))
.and_then(|v| v.as_bool())
.unwrap_or(true);
let partition_key = Diagnostics::KEY;
let cx = otel::span!(^
"handle_ariadne_diagnostics",
"color" = color,
);
let query_client = ctx.query_client();
let query_results = query_client
.prefix_internal(partition_key, String::new())
.with_context(cx)
.await;
let mut source_cache_reader = ctx.source_cache_reader();
let mut formatted_errors: Vec<String> = Vec::new();
for record_meta in query_results.records().iter() {
let Some(record_ref) = query_results.get(record_meta) else {
continue;
};
let Some(diagnostic) = record_ref.as_dyn_diagnostic() else {
continue;
};
let report = diagnostic.to_ariadne_report(&source_cache_reader);
let mut buffer = Vec::new();
if let Ok(()) = report.write(&mut source_cache_reader, &mut buffer)
&& let Ok(text) = String::from_utf8(buffer)
{
let output = if color {
text
} else {
anstream::adapter::strip_str(&text).to_string()
};
formatted_errors.push(output);
}
}
Ok(Some(serde_json::json!(formatted_errors)))
}