cratestack_parser/load/
diagnostics.rs1use std::path::{Path, PathBuf};
6
7use super::attribute::attribute;
8use super::graph::Graph;
9use super::sources::{FsSources, SchemaSources};
10use super::{LoadDiagnostics, LoadOptions, LoadedSchema, SchemaFile, collisions, merge};
11use crate::diagnostics::SchemaError;
12use crate::parse::{ParsedFile, expand_mixins};
13use crate::validate::validate_schema_collecting;
14
15pub fn load_schema_diagnostics(
18 path: impl AsRef<Path>,
19 options: &LoadOptions<'_>,
20) -> LoadDiagnostics {
21 let fs = FsSources;
22 let sources: &dyn SchemaSources = options.sources.unwrap_or(&fs);
23 let mut graph = Graph::new(sources);
24 let loaded = graph.load(path.as_ref(), options.follow_part_of);
25 let Graph {
26 files, attempted, ..
27 } = graph;
28 let named: Vec<(String, PathBuf)> = files
29 .iter()
30 .map(|f| (f.file.display.clone(), f.file.path.clone()))
31 .collect();
32 let stop = |errors: Vec<SchemaError>| LoadDiagnostics {
33 schema: None,
34 errors,
35 files: attempted.clone(),
36 named: named.clone(),
37 };
38 if let Err(error) = loaded {
39 return stop(vec![error]);
40 }
41 let attribute_all = |error: SchemaError, files: &[SchemaFile]| attribute(error, files.iter());
42 if let Err(error) = collisions::check(&files) {
43 let infos: Vec<SchemaFile> = files.iter().map(|f| f.file.clone()).collect();
44 return stop(vec![attribute_all(error, &infos)]);
45 }
46 let mut infos = Vec::with_capacity(files.len());
47 let mut parsed: Vec<ParsedFile> = Vec::with_capacity(files.len());
48 for loaded in files {
49 infos.push(loaded.file);
50 parsed.push(
51 loaded
52 .parsed
53 .expect("every file parsed once the graph loaded"),
54 );
55 }
56 let mut schema = merge::merge(parsed);
57 if let Err(error) = expand_mixins(&mut schema) {
58 return stop(vec![attribute_all(error, &infos)]);
59 }
60 let errors: Vec<SchemaError> = validate_schema_collecting(&infos[0].display, "", &schema)
61 .into_iter()
62 .map(|error| attribute_all(error, &infos))
63 .collect();
64 if !errors.is_empty() {
65 return stop(errors);
66 }
67 LoadDiagnostics {
68 schema: Some(LoadedSchema {
69 schema,
70 files: infos,
71 }),
72 errors: Vec::new(),
73 files: attempted,
74 named,
75 }
76}