use yog_data::Schema;
use yog_data::text::{Doc, LineCol};
use super::Problem;
#[derive(Debug, Default, Schema)]
pub struct Checked {
pub problems: Vec<Problem>,
}
pub fn check(path: &str, text: &str) -> Checked {
let doc = match yog_data::text::parse(text) {
Ok(doc) => doc,
Err(e) => {
return Checked {
problems: vec![Problem {
code: yog_ids::problem_code::SYNTAX.to_string(),
message: e.message,
path: String::new(),
line: Some(e.at.line),
col: Some(e.at.col),
}],
};
}
};
let Some(format) = yog_ids::Format::of_path(std::path::Path::new(path)) else {
return Checked::default();
};
let problems = yog_formats::problems(format, &doc.value)
.into_iter()
.map(|p| located(&doc, text, p))
.collect();
Checked { problems }
}
fn located(doc: &Doc, text: &str, p: yog_data::schema::Problem) -> Problem {
let spans = doc.spans_at(&p.path);
let start = match (p.at_key, spans.key) {
(true, Some(key)) => key.start,
_ => spans.span.start,
};
let at = LineCol::of(text, start as usize);
Problem {
code: p.code.to_string(),
message: p.message,
path: p.path.to_string(),
line: Some(at.line),
col: Some(at.col),
}
}