use std::ops::{Deref, DerefMut};
use mylsp::prelude::*;
use toml::Table;
#[derive(Clone, Debug)]
pub struct Doc {
uri: String,
text: String,
diagnostics: Diagnostics,
}
impl Doc {
pub fn new(uri: &str, text: String) -> Self {
let diagnostics = build_diagnostics(&text);
Self {
uri: uri.to_string(),
text,
diagnostics,
}
}
pub fn diagnostics(&self) -> &Diagnostics {
&self.diagnostics
}
}
fn build_diagnostics(text: &str) -> Diagnostics {
if let Err(err) = text.parse::<Table>() {
return vec![toml_error_to_diagnostic(text, &err)].into();
}
let items = vec![];
items.into()
}
fn toml_error_to_diagnostic(text: &str, err: &toml::de::Error) -> Diagnostic {
let range = Range::from_text_position_range(text, err.span().unwrap_or(0..0));
Diagnostic {
range,
severity: Some(DiagnosticSeverity::Error),
code: None,
code_description: None,
source: None,
message: err.message().to_string(),
tags: None,
related_information: None,
data: None,
}
}
#[derive(Default, Clone, Debug)]
pub struct Diagnostics(Vec<Diagnostic>);
impl From<Vec<Diagnostic>> for Diagnostics {
fn from(value: Vec<Diagnostic>) -> Self {
Self(value)
}
}
impl Deref for Diagnostics {
type Target = Vec<Diagnostic>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Diagnostics {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<&Doc> for Notification {
fn from(value: &Doc) -> Self {
(
"textDocument/publishDiagnostics",
PublishDiagnosticsParams {
uri: value.uri.clone(),
version: None,
diagnostics: value.diagnostics().to_vec(),
},
)
.into()
}
}
impl From<&Doc> for DocumentDiagnosticReport {
fn from(value: &Doc) -> Self {
DocumentDiagnosticReport {
kind: "full".to_string(),
result_id: None,
items: value.diagnostics().to_vec(),
}
}
}